[Openmcl-cvs-notifications] r8520 - /trunk/source/doc/src/openmcl-documentation.xml

gb at clozure.com gb at clozure.com
Wed Feb 20 09:18:19 EST 2008


Author: gb
Date: Wed Feb 20 09:18:19 2008
New Revision: 8520

Log:
valid XML.  Buggy, incomplete, valid XML

Modified:
    trunk/source/doc/src/openmcl-documentation.xml

Modified: trunk/source/doc/src/openmcl-documentation.xml
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/source/doc/src/openmcl-documentation.xml (original)
+++ trunk/source/doc/src/openmcl-documentation.xml Wed Feb 20 09:18:19 2008
@@ -1,12 +1,11 @@
 <?xml version=3D"1.0" encoding=3D"US-ASCII"?>
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oas=
is-open.org/docbook/xml/4.2/docbookx.dtd" [
-<!ENTITY rest "<varname><property>&amp;rest</property></varname>">
-<!ENTITY key "<varname><property>&amp;key</property></varname>">
-<!ENTITY optional "<varname><property>&amp;optional</property></varname>">
-<!ENTITY body "<varname><property>&amp;body</property></varname>">
-<!ENTITY aux "<varname><property>&amp;aux</property></varname>">
-<!ENTITY allow-other-keys
-         "<varname><property>&amp;allow-other-keys</property></varname>">
+<!ENTITY rest "<varname>&amp;rest</varname>">
+<!ENTITY key "<varname>&amp;key</varname>">
+<!ENTITY optional "<varname>&amp;optional</varname>">
+<!ENTITY body "<varname>&amp;body</varname>">
+<!ENTITY aux "<varname>&amp;aux</varname>">
+<!ENTITY allow-other-keys "<varname>&amp;allow-other-keys</varname>">
 ]>
 <book lang=3D"en">
  <bookinfo>
@@ -1073,10 +1072,10 @@
 	argument</para>
         <programlisting>
 $ cd ccl                        # wherever your ccl directory is
-$ ./<replaceable><kernel&gt; <boot_image&gt;</replaceable>
+$ ./KERNEL BOOT_IMAGE
 	</programlisting>
-        <para>Where <replaceable><kernel&gt;</replaceable> and
-        <replaceable><boot_image&gt;</replaceable> are the names of
+        <para>Where <replaceable>KERNEL</replaceable> and
+        <replaceable>BOOT_IMAGE</replaceable> are the names of
         the kernel and boot image appropriate to the platform you are
         running on.  See FIXTHIS</para>
         <para>That should load a few dozen fasl files (printing a
@@ -1291,7 +1290,7 @@
       code written to run under OpenMCL's interface to the native
       scheduler may be less portable to other CL implementations, many
       of which offer a cooperative scheduler and an API similar to
-      OpenMCL (< 0.14) 's.) At the same time, there's a large
+      OpenMCL (&lt; 0.14) 's.) At the same time, there's a large
       overlap in functionality in the two scheduling models, and it'll
       hopefully be possible to write interesting and useful MP code
       that's largely independent of the underlying scheduling
@@ -1475,7 +1474,7 @@
 ?
 =

 ? (process-run-function "sleeper" #'(lambda () (sleep 5) (break "broken")))
-#<PROCESS sleeper(1) [Enabled] #x3063B33E&gt;
+#&lt;PROCESS sleeper(1) [Enabled] #x3063B33E&gt;
 =

 ?
 ;;
@@ -1494,11 +1493,11 @@
 ;; process sleeper(1) now controls terminal input
 ;;
 > Break in process sleeper(1): broken
-> While executing: #<Anonymous Function #x3063B276&gt;
+> While executing: #&lt;Anonymous Function #x3063B276&gt;
 > Type :GO to continue, :POP to abort.
 > If continued: Return from BREAK.
 Type :? for other options.
-1 > :b
+1 &gt; :b
 (30C38E30) : 0 "Anonymous Function #x3063B276" 52
 (30C38E40) : 1 "Anonymous Function #x304984A6" 376
 (30C38E90) : 2 "RUN-PROCESS-INITIAL-FORM" 340
@@ -1522,10 +1521,10 @@
 ?
 =

 ? (process-run-function "sleep-60" #'(lambda () (sleep 60) (break "Huh?")))
-#<PROCESS sleep-60(1) [Enabled] #x3063BF26&gt;
+#&lt;PROCESS sleep-60(1) [Enabled] #x3063BF26&gt;
 =

 ? (process-run-function "sleep-5" #'(lambda () (sleep 5) (break "quicker")=
))
-#<PROCESS sleep-5(2) [Enabled] #x3063D0A6&gt;
+#&lt;PROCESS sleep-5(2) [Enabled] #x3063D0A6&gt;
 =

 ? ;;
 ;; Process sleep-5(2) needs access to terminal input.
@@ -1601,7 +1600,8 @@
     </sect1>
 =

     <sect1 id=3D"The-Threads-which-OpenMCL-Uses-for-Its-Own-Purposes">
-      <para>The Threads which OpenMCL Uses for Its Own Purposes
+      <title>The Threads which OpenMCL Uses for Its Own Purposes</title>
+      <para>
 In the "tty world", OpenMCL starts out with 2 lisp-level threads:</para>
       <programlisting>
 ? :proc
@@ -1722,7 +1722,6 @@
 =

     <sect1 id=3D"Threads-Dictionary">
       <title>Threads Dictionary</title>
-
       <refentry id=3D"f_all-processes">
 	<indexterm zone=3D"f_all-processes">
 	  <primary>all-processes</primary>
@@ -1758,11 +1757,11 @@
 	  <title>Description</title>
 =

 	  <para>Returns a list of all lisp processes (threads) known
-	  to OpenMCL as of the precise instant it&#39;s
-	  called. It&#39;s safe to traverse this list and to modify
-	  the cons cells that comprise that list (it&#39;s freshly
-	  consed.) Since other threads can create and kill threads at
-	  any time, there&#39;s generally no way to get an
+	  to OpenMCL as of
+	  the precise instant it&#39;s called. It&#39;s safe to traverse
+	  this list and to modify the cons cells that comprise that list
+	  (it&#39;s freshly consed.) Since other threads can create and kill
+	  threads at any time, there&#39;s generally no way to get an
 	  &#34;accurate&#34; list of all threads, and (generally) no
 	  sense in which such a list can be accurate.</para>
 	</refsect1>
@@ -1776,8 +1775,7 @@
 	</refsect1>
       </refentry>
 =

-
-       <refentry id=3D"f_make-process">
+      <refentry id=3D"f_make-process">
 	<indexterm zone=3D"f_make-process">
 	  <primary>make-process</primary>
 	</indexterm>
@@ -1944,1187 +1942,2444 @@
 	</refsect1>
       </refentry>
 =

-      <sect2 id=3D"PROCESS-SUSPEND">
-        <para>PROCESS-SUSPEND</para>
-        <informalfigure>process-suspend</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-SUSPEND &mdash; Suspends a specified process.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-suspend process
-	  =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>process
-            <variablelist>a lisp process (thread).</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>T if <literal>process</literal> had been runnabl=
eand is now suspended; NIL otherwise.  That is, T if<literal>process</liter=
al>'stransitioned from 0 to 1.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Suspends <literal>process</literal>, preventing it from
-running, and stopping it if it was already running. This is a fairly
-expensive operation, because it involves a few
-calls to the OS.  It also risks creating deadlock if used
-improperly, for instance, if the process being suspended owns a
-lock or other resource which another process will wait for.</para>
-        <para>Each
-call to <literal>process-suspend</literal> must be reversed by
-a matching call to =

-before <literal>process</literal> is able to run.  What
-<literal>process-suspend</literal> actually does is increment
-the  of
-<literal>process</literal>.</para>
-        <para>A process cannot suspend itself (although that was possible =
in
-some older OpenMCL releases and this documentation claimed that
-it still was.)</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">,</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para><literal>process-suspend</literal> was previously called
-<literal>process-disable</literal>.</para>
-        <para>now names a function for which there is no
-obvious inverse, so <literal>process-disable</literal>
-is no longer
-defined.</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-RESUME">
-        <para>PROCESS-RESUME</para>
-        <informalfigure>process-resume</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-RESUME &mdash; Resumes a specified process which had=
 previously
-been suspended by process-suspend.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-resume process
-	  =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>process
-            <variablelist>a lisp process (thread).</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>T if <literal>process</literal> had been suspend=
edand is now runnable; NIL otherwise.  That is, T if<literal>process</liter=
al>'stransitioned from  to 0.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Undoes the effect of a previous call to
-; if
-all such calls are undone, makes the process runnable. Has no
-effect if the process is not suspended.  What
-<literal>process-resume</literal> actually does is decrement
-the  of
-<literal>process</literal>, to a minimum of 0.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">,</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para>This was previously called PROCESS-ENABLE;
- now does something slightly
-different.</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-SUSPEND-COUNT">
-        <para>PROCESS-SUSPEND-COUNT</para>
-        <informalfigure>process-suspend-count</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-SUSPEND-COUNT &mdash; Returns the number of currentl=
y-pending suspensions
-applicable to a given process.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    process-suspend-count
+      <refentry id=3D"f_process-suspend">
+	<indexterm zone=3D"f_process-suspend">
+	  <primary>process-suspend</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-SUSPEND</refname>
+	  <refpurpose>Suspends a specified process.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+	=

+	<refsynopsisdiv>
+	  <synopsis><function>process-suspend</function> process
+	  =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+	  =

+	  <variablelist>
+	    <varlistentry>
+	      <term>process</term>
+	      <listitem>
+		<para>a lisp process (thread).</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>T if <varname>process</varname> had been runnable
+		and is now suspended; NIL otherwise.  That is, T if
+		<varname>process</varname>'s
+		<xref linkend=3D"f_process-suspend-count"/>
+		transitioned from 0 to 1.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Suspends <varname>process</varname>, preventing it from
+	  running, and stopping it if it was already running. This is a fairly
+	  expensive operation, because it involves a few
+	  calls to the OS.  It also risks creating deadlock if used
+	  improperly, for instance, if the process being suspended owns a
+	  lock or other resource which another process will wait for.</para>
+
+	  <para>
+	  Each
+	  call to <function>process-suspend</function> must be reversed by
+	  a matching call to <xref linkend=3D"f_process-resume"/>
+	  before <varname>process</varname> is able to run.  What
+	  <function>process-suspend</function> actually does is increment
+	  the <xref linkend=3D"f_process-suspend-count"/> of
+	  <varname>process</varname>.
+	  </para>
+
+	  <para>A process can suspend itself; it it&#39;s successful in doing
+	  so, then it can obviously only be resumed by some other
+	  process.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_process-resume"/></member>
+	    <member><xref linkend=3D"f_process-suspend-count"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+	  <para><function>process-suspend</function> was previously called
+	  <function>process-disable</function>.
+	  <xref linkend=3D"f_process-enable"/>
+	  now names a function for which there is no
+	  obvious inverse, so <function>process-disable</function>
+	  is no longer
+	  defined.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-resume">
+	<indexterm zone=3D"f_process-resume">
+	  <primary>process-resume</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-RESUME</refname>
+	  <refpurpose>Resumes a specified process which had previously
+	  been suspended by process-suspend.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-resume</function> process
+	  =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+	  =

+	  <variablelist>
+	    <varlistentry>
+	      <term>process</term>
+	      <listitem>
+		<para>a lisp process (thread).</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>T if <varname>process</varname> had been suspended
+		and is now runnable; NIL otherwise.  That is, T if
+		<varname>process</varname>'s
+		<xref linkend=3D"f_process-suspend-count"/>
+		transitioned from  to 0.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Undoes the effect of a previous call to
+	  <xref linkend=3D"f_process-suspend"/>; if
+	  all such calls are undone, makes the process runnable. Has no
+	  effect if the process is not suspended.  What
+	  <function>process-resume</function> actually does is decrement
+	  the <xref linkend=3D"f_process-suspend-count"/> of
+	  <varname>process</varname>, to a minimum of 0.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_process-suspend"/></member>
+	    <member><xref linkend=3D"f_process-suspend-count"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>
+	    This was previously called PROCESS-ENABLE;
+	    <xref linkend=3D"f_process-enable"/> now does something slightly
+	    different.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-suspend-count">
+	<indexterm zone=3D"f_process-suspend-count">
+	  <primary>process-suspend-count</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-SUSPEND-COUNT</refname>
+	  <refpurpose>Returns the number of currently-pending suspensions
+	  applicable to a given process.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>process-suspend-count</function>
 	    process =3D> result
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>process
-            <variablelist>a lisp process (thread).</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>The number of "outstanding" calls on<literal>pro=
cess</literal>, or NIL if<literal>process</literal> has expired.</variablel=
ist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>An "outstanding"  call
-is one which has not yet been reversed by a call to
-.  A process expires when
-its initial function returns, although it may later be
-reset.</para>
-        <para>A process is <emphasis>runnable</emphasis> when it has a
-<literal>process-suspend-count</literal> of 0, has been
-preset as by , and has been
-enabled as by .  Newly-created
-processes have a <literal>process-suspend-count</literal> of
-0.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">,</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-PRESET">
-        <para>PROCESS-PRESET</para>
-        <informalfigure>process-preset</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-PRESET &mdash; Sets the initial function and argumen=
ts of a specified
-process.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-preset
-	  process function &amp;rest args
-	  =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>process
-            <variablelist>a lisp process (thread).</variablelist>
-          </indexterm><indexterm>function
-            <variablelist>a function, designated by itself or by a symbolw=
hich names it.</variablelist>
-          </indexterm><indexterm>args
-            <variablelist>a list of values, appropriate as arguments to<li=
teral>function</literal>.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>undefined.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Typically used to initialize a newly-created or newly-reset
-process, setting things up so that when <literal>process</literal>
-becomes enabled, it will begin execution by
-applying <literal>function</literal> to <literal>args</literal>.
-<literal>process-preset</literal> does not enable
-<literal>process</literal>,
-although a process must be <literal>process-preset</literal>
-before it can be enabled.  Processes are normally enabled by
-.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, ,</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-ENABLE">
-        <para>PROCESS-ENABLE</para>
-        <informalfigure>process-enable</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-ENABLE &mdash; Begins executing the initial function=
 of a specified
-process.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-enable
-	  process &amp;optional timeout
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>process
-            <variablelist>a lisp process (thread).</variablelist>
-          </indexterm><indexterm>timeout
-            <variablelist>a time interval in seconds.  May be anynon-negat=
ive real number the <literal>floor</literal> ofwhich fits in 32 bits.  The =
default is 1.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>undefined.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Tries to begin the execution of <literal>process</literal>.
-An error is signaled if <literal>process</literal> has never
-been .  Otherwise,
-<literal>process</literal> invokes its initial function.</para>
-        <para><literal>process-enable</literal> attempts to
-synchronize with <literal>process</literal>, which is presumed
-to be reset or in the act of resetting itself.  If this attempt
-is not successful within the time interval specified by
-<literal>timeout</literal>, a continuable error is signaled,
-which offers the opportunity to continue waiting.</para>
-        <para>A process cannot meaningfully attempt to enable itself.</par=
a>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, ,</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para>It would be nice to have more discussion of what it means
-to synchronize with the process.</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-RUN-FUNCTION">
-        <para>PROCESS-RUN-FUNCTION</para>
-        <informalfigure>process-run-function</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-RUN-FUNCTION &mdash; Creates a process, presets it, =
and enables it.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-run-function
-	  process-specifier function &amp;rest args =3D> process
-</programlisting>
-        <term><indexterm>process-specifier
-            <variablelist><literal>name</literal> |(<literal>&amp;key</lit=
eral> <literal>name</literal><literal>persistent</literal><literal>priority=
</literal><literal>class</literal><literal>stack-size</literal><literal>vst=
ack-size</literal><literal>tstack-size</literal>)</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>a string, used to identify the process.Passed to=
 <literal>make-process</literal>.</variablelist>
-          </indexterm><indexterm>function
-            <variablelist>a function, designated by itself or by a symbolw=
hich names it.  Passed to<literal>preset-process</literal>.</variablelist>
-          </indexterm><indexterm>persistent
-            <variablelist>a boolean, passed to <literal>make-process</lite=
ral>.</variablelist>
-          </indexterm><indexterm>priority
-            <variablelist>ignored.</variablelist>
-          </indexterm><indexterm>class
-            <variablelist>a subclass of CCL:PROCESS.  Passed to<literal>ma=
ke-process</literal>.</variablelist>
-          </indexterm><indexterm>stack-size
-            <variablelist>a size, in bytes.  Passed to<literal>make-proces=
s</literal>.</variablelist>
-          </indexterm><indexterm>vstack-size
-            <variablelist>a size, in bytes.  Passed to<literal>make-proces=
s</literal>.</variablelist>
-          </indexterm><indexterm>tstack-size
-            <variablelist>a size, in bytes.  Passed to<literal>make-proces=
s</literal>.</variablelist>
-          </indexterm><indexterm>process
-            <variablelist>the newly-created process.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Creates a lisp process (thread) via
-,
-presets it via , and
-enables it via .  This means
-that <literal>process</literal> will immediately begin to
-execute.
-<literal>process-run-function</literal> is
-the simplest way to create and run a process.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, ,</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-INTERRUPT">
-        <para>PROCESS-INTERRUPT</para>
-        <informalfigure>process-interrupt</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-INTERRUPT &mdash; Arranges for the target process to=
 invoke a
-specified function at some point in the near future, and then
-return to what it was doing.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-interrupt
-	  process function &amp;rest args =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>process
-            <variablelist>a lisp process (thread).</variablelist>
-          </indexterm><indexterm>function
-            <variablelist>a function.</variablelist>
-          </indexterm><indexterm>args
-            <variablelist>a list of values, appropriate as arguments to<li=
teral>function</literal>.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>the result of applying <literal>function</litera=
l>to <literal>args</literal> if <literal>proceess</literal>is the <literal>=
current-process</literal>, otherwiseNIL.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Arranges for <literal>process</literal> to apply <literal>fu=
nction</literal> to <literal>args</literal> at
-some point in the near future (interrupting whatever <literal>process</lit=
eral>
-was doing.) If <literal>function</literal> returns normally, <literal>proc=
ess</literal>
-resumes execution at the point at which it was interrupted.</para>
-        <para><literal>process</literal> must be in an enabled state in or=
der to respond to a
-<literal>process-interrupt</literal> request.  It's perfectly legal for a =
process
-to call <literal>process-interrupt</literal> on itself.</para>
-        <para><literal>process-interrupt</literal> uses asynchronous POSIX=
 signals to interrupt
-threads. If the thread being interrupted is executing lisp code, it
-can respond to the interrupt almost immediately (as soon as it has
-finished pseudo-atomic operations like consing and stack-frame
-initialization.)</para>
-        <para>If the interrupted thread is blocking in a system call, that=
 system
-call is aborted by the signal and the interrupt is handled on return.</par=
a>
-        <para>Beginning with the version 1.1 prereleases of OpenMCL interr=
upts are
-disabled in <literal>unwind-protect</literal> cleanup forms and in any sta=
ck-unwinding
-code between the point of the <literal>throw</literal> and the correspondi=
ng CATCH
-target.  If interrupts were enabled at the time that the CATCH was
-established, then any interrupt that had been deferred during
-unwinding will be taken just before the transfer to <literal>catch</litera=
l> target
-(after all of that unwinding is complete.)</para>
-        <para>If an <literal>unwind-protect</literal> cleanup form actuall=
y does something that
-needs to be interruptible, it's necessary to use
-<literal>with-interrupts-enabled</literal>.  (This actually happens somewh=
ere in
-the code which waits for external processes to complete; some of that
-waiting occurred within an unwind-protect cleanup, and interrupts
-needed to be explicitly enabled in that case in order to make the wait
-interruptible.)</para>
-        <para>Note that <literal>(without-interrupts (throw ...))</literal=
> wouldn't have the intended
-effect, since the <literal>throw</literal> would cause execution to exit t=
he extent of
-the <literal>without-interrupts</literal>.</para>
-        <para>In versions prior to 1.1, interrupts could occur at arbitrar=
y times
-during the process of unwinding the stack and executing intervening
-cleanup forms.</para>
-        <para>It is still difficult to reliably interrupt arbitrary foreig=
n code
-(that may be stateful or otherwise non-reentrant); the interrupt
-request is handled when such foreign code returns to or enters lisp.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues"></para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para>It would probably be better for <literal>result</literal> to=
 always be NIL, since
-the present behaviour is inconsistent.</para>
-        <para><literal>Process-interrupt</literal> works by sending signal=
s between threads, via
-the C function <literal>#_pthread_signal</literal>.  It could be argued th=
at it
-should be done in one of several possible other ways under Darwin, to
-make it practical to asynchronously interrupt things which make heavy
-use of the Mach nanokernel.</para>
-      </sect2>
-
-      <sect2 id=3D"iCURRENT-PROCESS-">
-        <para>*CURRENT-PROCESS*</para>
-        <informalfigure>*current-process*</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>*CURRENT-PROCESS* &mdash; Bound in each process, to that pro=
cess
-itself.</para>
-        <para>Variable</para>
-        <bridgehead renderas=3D"sect3">Value Type</bridgehead>
-        <para>A lisp process (thread).</para>
-        <bridgehead renderas=3D"sect3">Initial Value</bridgehead>
-        <para>Bound separately in each process, to that process itself.</p=
ara>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Used when lisp code needs to find out what process it is
-executing in.  Shouldn't be set by user code.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues"></para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-RESET">
-        <para>PROCESS-RESET</para>
-        <informalfigure>process-reset</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-RESET &mdash; Causes a specified process to cleanly =
exit from
-any ongoing computation.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-reset
-	  process &amp;optional kill-option =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>process
-            <variablelist>a lisp process (thread).</variablelist>
-          </indexterm><indexterm>kill-option
-            <variablelist>a generalized boolean.  The default is T.</varia=
blelist>
-          </indexterm><indexterm>result
-            <variablelist>undefined.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Causes <literal>process</literal> to cleanly exit
-from any ongoing computation.  If <literal>kill-option</literal>
-is true, <literal>process</literal> then exits.  Otherwise, it
-enters a state where it can be
-. This
-is implemented by signaling a condition of type PROCESS-RESET;
-user-defined condition handlers should generally refrain from
-attempting to handle conditions of this type.</para>
-        <para>A process can meaningfully reset itself.</para>
-        <para>There is in general no way to know precisely when
-<literal>process</literal>
-has completed the act of resetting or killing itself; a process
-which has either entered the limbo of the reset state or exited
-has few ways of communicating either fact.</para>
-        <para>can reliably determine when a process has entered
-the "limbo of the reset state", but can't predict how long the
-clean exit from ongoing computation might take: that depends on
-the behavior of <literal>unwind-protect</literal> cleanup
-forms, and of the OS scheduler.</para>
-        <para>Resetting a process other than
- involves the
-use of .</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">,</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-KILL">
-        <para>PROCESS-KILL</para>
-        <informalfigure>process-kill</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-KILL &mdash; Causes a specified process to cleanly e=
xit from any
-ongoing computation, and then exit.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-kill process
-	  =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>process
-            <variablelist>a lisp process (thread).</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>undefined.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Entirely equivalent to calling
-(PROCESS-RESET PROCESS T).  Causes <literal>process</literal>
-to cleanly exit from any ongoing computation, and then exit.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">,</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-ABORT">
-        <para>PROCESS-ABORT</para>
-        <informalfigure>process-abort</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-ABORT &mdash; Causes a specified process to process =
an abort
-condition, as if it had invoked
-<literal>abort</literal>.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-abort process
-	  &amp;optional condition
-	  =3D> NIL
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>process
-            <variablelist>a lisp process (thread).</variablelist>
-          </indexterm><indexterm>condition
-            <variablelist>a lisp condition.  The default is NIL.</variable=
list>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Entirely equivalent to calling
-( <literal>process</literal>
-(<literal>lambda</literal> ()
-(<literal>abort</literal> <literal>condition</literal>))).
-Causes <literal>process</literal> to transfer control to the
-applicable handler or restart for <literal>abort</literal>.</para>
-        <para>If <literal>condition</literal> is non-NIL,
-<literal>process-abort</literal> does not consider any
-handlers which are explicitly bound to conditions other than
-<literal>condition</literal>.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">,</para>
-      </sect2>
-
-      <sect2 id=3D"iTICKS-PER-SECOND-">
-        <para>*TICKS-PER-SECOND*</para>
-        <informalfigure>*ticks-per-second*</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>*TICKS-PER-SECOND* &mdash; Bound to the clock resolution of =
the OS
-scheduler.</para>
-        <para>Variable</para>
-        <bridgehead renderas=3D"sect3">Value Type</bridgehead>
-        <para>A positive integer.</para>
-        <bridgehead renderas=3D"sect3">Initial Value</bridgehead>
-        <para>The clock resoluton of the OS scheduler.  Currently,
-both LinuxPPC and DarwinPPC yeild an initial value of 100.</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>This value is ordinarily of marginal interest at best,
-but, for backward compatibility, some functions accept timeout
-values expressed in "ticks".  This value gives the number of
-ticks per second.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues"></para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-WHOSTATE">
-        <para>PROCESS-WHOSTATE</para>
-        <informalfigure>process-whostate</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-WHOSTATE &mdash; Returns a string which describes th=
e status of
-a specified process.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-whostate process
-	  =3D> whostate
-</programlisting>
-        <term><indexterm>process
-            <variablelist>a lisp process (thread).</variablelist>
-          </indexterm><indexterm>whostate
-            <variablelist>a string which describes the "state" of<literal>=
process</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>This information is primarily for the benefit of
-debugging tools.  <literal>whostate</literal> is a terse report
-on what <literal>process</literal> is doing, or not doing,
-and why.</para>
-        <para>If the process is currently waiting in a call to
- or
-, its
-<literal>process-whostate</literal> will be the value
-which was passed to that function as <literal>whostate</literal>.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, ,</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para>This should arguably be SETFable, but doesn't seem to
-ever have been.</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-ALLOW-SCHEDULE">
-        <para>PROCESS-ALLOW-SCHEDULE</para>
-        <informalfigure>process-allow-schedule</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-ALLOW-SCHEDULE &mdash; Used for cooperative multitas=
king; probably never
-necessary.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-allow-schedule
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Advises the OS scheduler that the current thread has nothing
-useful to do and that it should try to find some other thread to
-schedule in its place. There's almost always a better
-alternative, such as waiting for some specific event to
-occur.  For example, you could use a lock or semaphore.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , ,</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para>This is a holdover from the days of cooperative
-multitasking.  All modern general-purpose operating systems use
-preemptive multitasking.</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-WAIT">
-        <para>PROCESS-WAIT</para>
-        <informalfigure>process-wait</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-WAIT &mdash; Causes the current lisp process (thread=
) to wait for
-a given
-predicate to return true.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-wait
-	  whostate function &amp;rest args =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>whostate
-            <variablelist>a string, which will be the value ofwhile the pr=
ocess is waiting.</variablelist>
-          </indexterm><indexterm>function
-            <variablelist>a function, designated by itself or by a symbolw=
hich names it.</variablelist>
-          </indexterm><indexterm>args
-            <variablelist>a list of values, appropriate as arguments to<li=
teral>function</literal>.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>NIL.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Causes the current lisp process (thread) to repeatedly
-apply <literal>function</literal> to
-<literal>args</literal> until the call returns a true result, then
-returns NIL. After
-each failed call, yields the CPU as if by
-.</para>
-        <para>As with , it's almost
-always more efficient to wait for some
-specific event to occur; this isn't exactly busy-waiting, but
-the OS scheduler can do a better job of scheduling if it's given
-the relevant information.  For example, you could use a lock
-or semaphore.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-WAIT-WITH-TIMEOUT">
-        <para>PROCESS-WAIT-WITH-TIMEOUT</para>
-        <informalfigure>process-wait-with-timeout</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-WAIT-WITH-TIMEOUT &mdash; Causes the current thread =
to wait for a given
-predicate to return true, or for a timeout to expire.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-wait-with-timeout
-	  whostate ticks function args =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>whostate
-            <variablelist>a string, which will be the value ofwhile the pr=
ocess is waiting.</variablelist>
-          </indexterm><indexterm>ticks
-            <variablelist>either a positive integer expressing a durationi=
n "ticks" (see ),or NIL.</variablelist>
-          </indexterm><indexterm>function
-            <variablelist>a function, designated by itself or by a symbolw=
hich names it.</variablelist>
-          </indexterm><indexterm>args
-            <variablelist>a list of values, appropriate as arguments to<li=
teral>function</literal>.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>T if <literal>process-wait-with-timeout</literal=
>returned because its <literal>function</literal> returnedtrue, or NIL if i=
t returned because the duration<literal>ticks</literal> has been exceeded.<=
/variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>If <literal>ticks</literal> is NIL, behaves exactly like
-, except for returning T.
-Otherwise, <literal>function</literal> will be tested repeatedly,
-in the same
-kind of test/yield loop as in >
-until either <literal>function</literal> returns true,
-or the duration <literal>ticks</literal> has been exceeded.</para>
-        <para>Having already read the descriptions of
- and
-, the
-astute reader has no doubt anticipated the observation that
-better alternatives should be used whenever possible.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"WITHOUT-INTERRUPTS">
-        <para>WITHOUT-INTERRUPTS</para>
-        <informalfigure>without-interrupts</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>WITHOUT-INTERRUPTS &mdash; Evaluates its body in an environm=
ent in which
-process-interrupt requests are deferred.</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-without-interrupts
-	  &amp;body body =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>body
-            <variablelist>an implicit progn.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>the primary value returned by<literal>body</lite=
ral>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Executes <literal>body</literal> in an environment in which
- requests are deferred. As noted in the
-description of , this has nothing to do with
-the scheduling of other threads; it may be necessary to inhibit
- handling when (for instance) modifying some
-data structure (for which the current thread holds an appropriate
-lock) in some manner that's not reentrant.</para>
-        <para>Beginning with the version 1.1 prereleases of OpenMCL interr=
upts are
-disabled in <literal>unwind-protect</literal> cleanup forms and in any
-stack-unwinding code between the point of the <literal>throw</literal> and=
 the
-corresponding CATCH target. If an <literal>unwind-protect</literal> cleanu=
p form
-actually does something that needs to be interruptible, it's necessary
-to use <literal>with-interrupts-enabled</literal>. In versions prior to 1.=
1,
-interrupts can occur at arbitrary times during the process of
-unwinding the stack and executing intervening cleanup forms.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues"></para>
-      </sect2>
-
-      <sect2 id=3D"MAKE-LOCK">
-        <para>MAKE-LOCK</para>
-        <informalfigure>make-lock</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>MAKE-LOCK &mdash; Creates and returns a lock object, which c=
an
-be used for synchronization between threads.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-make-lock &amp;optional
-	  name =3D> lock
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>any lisp object; saved as part of<literal>lock</=
literal>.  Typically a string or symbolwhich may appear in the sof threads =
which are waiting for <literal>lock</literal>.</variablelist>
-          </indexterm><indexterm>lock
-            <variablelist>a newly-allocated object of type CCL:LOCK.</vari=
ablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Creates and returns a lock object, which can
-be used to synchronize access to some shared resource.
-<literal>lock</literal> is
-initially in a "free" state; a lock can also be
-"owned" by a
-thread.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"WITH-LOCK-GRABBED">
-        <para>WITH-LOCK-GRABBED</para>
-        <informalfigure>with-lock-grabbed</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>WITH-LOCK-GRABBED &mdash; Waits until a given lock can be ob=
tained, then
-evaluates its body with the lock held.</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-with-lock-grabbed
-	  (lock) &amp;body body
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>lock
-            <variablelist>an object of type CCL:LOCK.</variablelist>
-          </indexterm><indexterm>body
-            <variablelist>an implicit progn.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>the primary value returned by<literal>body</lite=
ral>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Waits until <literal>lock</literal> is either free or
-owned by the calling
-thread, then excutes <literal>body</literal> with the
-lock owned by the calling thread. If <literal>lock</literal>
-was free when <literal>with-lock-grabbed</literal> was called,
-it is restored to a free state after <literal>body</literal>
-is executed.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"GRAB-LOCK">
-        <para>GRAB-LOCK</para>
-        <informalfigure>grab-lock</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>GRAB-LOCK &mdash; Waits until a given lock can be obtained, =
then
-obtains it.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-grab-lock lock
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>lock
-            <variablelist>an object of type CCL:LOCK.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Blocks until <literal>lock</literal> is owned by the
-calling thread.</para>
-        <para>The macro =

-<emphasis>could</emphasis> be defined in
-terms of <literal>grab-lock</literal> and
-, but it is actually
-implemented at a slightly lower level.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"RELEASE-LOCK">
-        <para>RELEASE-LOCK</para>
-        <informalfigure>release-lock</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>RELEASE-LOCK &mdash; Relinquishes ownership of a given lock.=
</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-release-lock lock
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>lock
-            <variablelist>an object of type CCL:LOCK.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Signals an error of type CCL:LOCK-NOT-OWNER if
-<literal>lock</literal>
-is not already owned by the calling thread; otherwise, undoes the
-effect of one previous
-.  If this means that
-<literal>release-lock</literal> has now been called on
-<literal>lock</literal> the same number of times as
- has, <literal>lock</literal>
-becomes free.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"TRY-LOCK">
-        <para>TRY-LOCK</para>
-        <informalfigure>try-lock</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>TRY-LOCK &mdash; Obtains the given lock, but only if it is n=
ot
-necessary to wait for it.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-try-lock lock =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>lock
-            <variablelist>an object of type CCL:LOCK.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>T if <literal>lock</literal> has been obtained,o=
r NIL if it has not.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Tests whether <literal>lock</literal>
-can be obtained without blocking - that is, either
-<literal>lock</literal> is already free, or it is already owned
-by .  If it can,
-causes it to
-be owned by the calling lisp process (thread) and returns T.
-Otherwise, the lock
-is already owned by another thread and cannot be obtained without
-blocking; NIL is returned in this case.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"MAKE-READ-WRITE-LOCK">
-        <para>MAKE-READ-WRITE-LOCK</para>
-        <informalfigure>make-read-write-lock</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>MAKE-READ-WRITE-LOCK &mdash; Creates and returns a read-writ=
e lock, which can
-be used for synchronization between threads.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-make-read-write-lock
-	  =3D> read-write-lock
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>read-write-lock
-            <variablelist>a newly-allocated object of typeCCL:READ-WRITE-L=
OCK.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Creates and returns an object of type CCL::READ-WRITE-LOCK.
-A read-write lock may, at any given time, belong to any number
-of lisp processes (threads) which act as "readers"; or, it may
-belong to at most one process which acts as a "writer".  A
-read-write lock may never be held by a reader at the same time as
-a writer.  Intially, <literal>read-write-lock</literal> has
-no readers and no writers.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , ,</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para>There probably should be some way to
-atomically "promote" a reader, making it a writer without
-releasing the lock, which could otherwise cause delay.</para>
-      </sect2>
-
-      <sect2 id=3D"WITH-READ-LOCK">
-        <para>WITH-READ-LOCK</para>
-        <informalfigure>with-read-lock</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>WITH-READ-LOCK &mdash; Waits until a given lock is available=
 for
-read-only access, then evaluates its body with the lock
-held.</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-with-read-lock
-	  (read-write-lock) &amp;body body =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>read-write-lock
-            <variablelist>an object of typeCCL:READ-WRITE-LOCK.</variablel=
ist>
-          </indexterm><indexterm>body
-            <variablelist>an implicit progn.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>the primary value returned by<literal>body</lite=
ral>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Waits until <literal>read-write-lock</literal> has no
-writer,
-ensures that  is a
-reader of it, then executes <literal>body</literal>.</para>
-        <para>After executing <literal>body</literal>, if
- was not a reader of
-<literal>read-write-lock</literal> before
-<literal>with-read-lock</literal> was called, the lock is
-released.  If it was already a reader, it remains one.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"WITH-WRITE-LOCK">
-        <para>WITH-WRITE-LOCK</para>
-        <informalfigure>with-write-lock</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>WITH-WRITE-LOCK &mdash; Waits until the given lock is availa=
ble for write
-access, then executes its body with the lock held.</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-with-write-lock
-	  (read-write-lock) &amp;body body
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>read-write-lock
-            <variablelist>an object of typeCCL:READ-WRITE-LOCK.</variablel=
ist>
-          </indexterm><indexterm>body
-            <variablelist>an implicit progn.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>the primary value returned by<literal>body</lite=
ral>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Waits until <literal>read-write-lock</literal> has no
-readers and no writer other than ,
-then ensures that  is the
-writer of it.  With the lock held, executes <literal>body</literal>.</para>
-        <para>After executing <literal>body</literal>, if
- was not the writer of
-<literal>read-write-lock</literal> before
-<literal>with-write-lock</literal> was called, the lock is
-released.  If it was already the writer, it remains the
-writer.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"MAKE-SEMAPHORE">
-        <para>MAKE-SEMAPHORE</para>
-        <informalfigure>make-semaphore</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>MAKE-SEMAPHORE &mdash; Creates and returns a semaphore, whic=
h can be used
-for synchronization between threads.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-make-semaphore
-	  =3D> semaphore
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>semaphore
-            <variablelist>a newly-allocated object of type CCL:SEMAPHORE.<=
/variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Creates and returns an object of type CCL:SEMAPHORE.
-A semaphore has an associated "count" which may be incremented
-and decremented atomically; incrementing it represents sending
-a signal, and decrementing it represents handling that signal.
-<literal>semaphore</literal> has an initial count of 0.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"SIGNAL-SEMAPHORE">
-        <para>SIGNAL-SEMAPHORE</para>
-        <informalfigure>signal-semaphore</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SIGNAL-SEMAPHORE &mdash; Atomically increments the count of =
a given
-semaphore.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-signal-semaphore
-	  semaphore =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>semaphore
-            <variablelist>an object of type CCL:SEMAPHORE.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>an integer representing an error identifierwhich=
 was returned by the underlying OS call.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Atomically increments <literal>semaphore</literal>'s
-"count" by 1; this
-may enable a waiting thread to resume execution.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , , ,</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para><literal>result</literal> should probably be interpreted
-and acted on by <literal>signal-semaphore</literal>, because
-it is not likely to be meaningful to a lisp program, and the
-most common cause of failure is a type error.</para>
-      </sect2>
-
-      <sect2 id=3D"WAIT-ON-SEMAPHORE">
-        <para>WAIT-ON-SEMAPHORE</para>
-        <informalfigure>wait-on-semaphore</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>WAIT-ON-SEMAPHORE &mdash; Waits until the given semaphore ha=
s a positive
-count which can be atomically decremented.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-wait-on-semaphore
-	  semaphore =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>semaphore
-            <variablelist>an object of type CCL:SEMAPHORE.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>WAIT-ON-SEMAPHORE always returns T.</variablelis=
t>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Waits until <literal>semaphore</literal>
-has a positive count that can be
-atomically decremented; this will succeed exactly once for each
-corresponding call to SIGNAL-SEMAPHORE.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , , ,</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-      </sect2>
-
-      <sect2 id=3D"TIMED-WAIT-ON-SEMAPHORE">
-        <para>TIMED-WAIT-ON-SEMAPHORE</para>
-        <informalfigure>timed-wait-on-semaphore</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>TIMED-WAIT-ON-SEMAPHORE &mdash; Waits until the given semaph=
ore has a postive
-count which can be atomically decremented, or until a timeout
-expires.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-timed-wait-on-semaphore
-	  semaphore timeout =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>semaphore
-            <variablelist>An object of type CCL:SEMAPHORE.</variablelist>
-          </indexterm><indexterm>timeout
-            <variablelist>a time interval in seconds.  May be anynon-negat=
ive real number the <literal>floor</literal> ofwhich fits in 32 bits.  The =
default is 1.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>T if <literal>timed-wait-on-semaphore</literal>r=
eturned because it was able to decrement the count of<literal>semaphore</li=
teral>; NIL if it returned becausethe duration <literal>timeout</literal> h=
as beenexceeded.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Waits until <literal>semaphore</literal>
-has a positive count that can be
-atomically decremented, or until the duration
-<literal>timeout</literal> has
-elapsed.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-INPUT-WAIT">
-        <para>PROCESS-INPUT-WAIT</para>
-        <informalfigure>process-input-wait</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-INPUT-WAIT &mdash; Waits until input is available on=
 a given
-file-descriptor.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-input-wait
-	  fd &amp;optional timeout
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>fd
-            <variablelist>a file descriptor, which is a non-negative integ=
erused by the OS to refer to an open file, socket, or similarI/O connection=
.  See CCL::STREAM-DEVICE.</variablelist>
-          </indexterm><indexterm>timeout
-            <variablelist>either NIL, or a time interval in seconds.  May =
be anynon-negative real number the <literal>floor</literal> ofwhich fits in=
 32 bits.  The default is NIL.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Wait until input is available on <literal>fd</literal>.
-This uses the <literal>select()</literal> system call, and is
-generally a fairly
-efficient way of blocking while waiting for input. More
-accurately, <literal>process-input-wait</literal>
-waits until it's possible to read
-from fd without blocking, or until <literal>timeout</literal>, if
-it is not NIL, has been exceeded.</para>
-        <para>Note that it's possible to read without blocking if
-the file is at its end - although, of course, the read will
-return zero bytes.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , ,</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para><literal>process-input-wait</literal> has a timeout paramete=
r,
-and
- does not.  This
-inconsistency should probably be corrected.</para>
-      </sect2>
-
-      <sect2 id=3D"PROCESS-OUTPUT-WAIT">
-        <para>PROCESS-OUTPUT-WAIT</para>
-        <informalfigure>process-output-wait</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PROCESS-OUTPUT-WAIT &mdash; Waits until output is possible o=
n a given file
-descriptor.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-process-output-wait fd
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>fd
-            <variablelist>a file descriptor, which is a non-negative integ=
erused by the OS to refer to an open file, socket, or similarI/O connection=
.  See CCL::STREAM-DEVICE.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Wait until output is possible on <literal>fd</literal>.
-This uses the <literal>select()</literal> system call, and is
-generally a fairly
-efficient way of blocking while waiting to output.</para>
-        <para>If <literal>process-output-wait</literal> is called on
-a network socket which has not yet established a connection, it
-will wait until the connection is established.  This is an
-important use, often overlooked.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , ,</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead> =

-        <para>has a timeout parameter,
-and
-<literal>process-output-wait</literal> does not.  This
-inconsistency should probably be corrected.</para>
-      </sect2>
-
-      <sect2 id=3D"WITH-TERMINAL-INPUT">
-        <para>WITH-TERMINAL-INPUT</para>
-        <informalfigure>with-terminal-input</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>WITH-TERMINAL-INPUT &mdash; Executes its body in an environm=
ent with exclusive
-read access to the terminal.</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-with-terminal-input
-	  &amp;body body =3D> result
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>body
-            <variablelist>an implicit progn.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>the primary value returned by<literal>body</lite=
ral>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Requests exclusive read access to the standard terminal
-stream, <literal>*terminal-io*</literal>.  Executes
-<literal>body</literal> in an environment with that access.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, :Y, , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"iREQUEST-TERMINAL-INPUT-VIA-BREAK-">
-        <para>*REQUEST-TERMINAL-INPUT-VIA-BREAK*</para>
-        <informalfigure>request-terminal-input-via-break</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>*REQUEST-TERMINAL-INPUT-VIA-BREAK* &mdash; Controls how atte=
mpts to obtain ownership of
-terminal input are made.</para>
-        <para>Variable</para>
-        <bridgehead renderas=3D"sect3">Value Type</bridgehead>
-        <para>A boolean.</para>
-        <bridgehead renderas=3D"sect3">Initial Value</bridgehead>
-        <para>NIL.</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Controls how attempts to obtain ownership of terminal input
-are made. When NIL, a message is printed on *TERMINAL-IO*;
-it's expected that the user will later yield
-control of the terminal via the :Y toplevel command. When T, a
-BREAK condition is signaled in the owning process; continuing from
-the break loop will yield the terminal to the requesting process
-(unless the :Y command was already used to do so in the break
-loop.)</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, :Y, , , , ,</para>
-      </sect2>
-
-      <sect2 id=3D"iY">
-        <para>:Y</para>
-        <informalfigure>:y</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>:Y &mdash; Yields control of terminal input to a specified
-lisp process (thread).</para>
-        <para>Toplevel Command</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-(:y p)
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>p
-            <variablelist>a lisp process (thread), designated either byan =
integer which matches its<literal>process-serial-number</literal>,or by a s=
tring which is <literal>equal</literal> toits <literal>process-name</litera=
l>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>:Y is a toplevel command, not a function.  As such, it
-can only be used interactively, and only from the initial
-process.</para>
-        <para>The command yields control of terminal input to the
-process <literal>p</literal>, which must have used
- to request access to the
-terminal input stream.</para>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">, , , , , ,</para>
-      </sect2>
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>process</term>
+	      <listitem>
+		<para>a lisp process (thread).</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>The number of "outstanding"
+		<xref linkend=3D"f_process-suspend"/> calls on
+		<varname>process</varname>, or NIL if
+		<varname>process</varname> has expired.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>An "outstanding" <xref linkend=3D"f_process-suspend"/> call
+	  is one which has not yet been reversed by a call to
+	  <xref linkend=3D"f_process-resume"/>.  A process expires when
+	  its initial function returns, although it may later be
+	  reset.</para>
+
+	  <para>A process is <emphasis>runnable</emphasis> when it has a
+	  <function>process-suspend-count</function> of 0, has been
+	  preset as by <xref linkend=3D"f_process-preset"/>, and has been
+	  enabled as by <xref linkend=3D"f_process-enable"/>.  Newly-created
+	  processes have a <function>process-suspend-count</function> of
+	  0.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_process-suspend"/></member>
+	    <member><xref linkend=3D"f_process-resume"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-preset">
+	<indexterm zone=3D"f_process-preset">
+	  <primary>process-preset</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-PRESET</refname>
+	  <refpurpose>Sets the initial function and arguments of a specified
+	  process.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-preset</function>
+	  process function &rest; args
+	  =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>process</term>
+	      <listitem>
+		<para>a lisp process (thread).</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>function</term>
+	      <listitem>
+		<para>a function, designated by itself or by a symbol
+		which names it.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>args</term>
+	      <listitem>
+		<para>a list of values, appropriate as arguments to
+		<varname>function</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>undefined.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Typically used to initialize a newly-created or newly-reset
+	  process, setting things up so that when <varname>process</varname>
+	  becomes enabled, it will begin execution by
+	  applying <varname>function</varname> to <varname>args</varname>.
+	  <function>process-preset</function> does not enable
+	  <varname>process</varname>,
+	  although a process must be <function>process-preset</function>
+	  before it can be enabled.  Processes are normally enabled by
+	  <xref linkend=3D"f_process-enable"/>.
+	  </para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-process"/></member>
+	    <member><xref linkend=3D"f_process-enable"/></member>
+	    <member><xref linkend=3D"f_process-run-function"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-enable">
+	<indexterm zone=3D"f_process-enable">
+	  <primary>process-enable</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-ENABLE</refname>
+	  <refpurpose>Begins executing the initial function of a specified
+	  process.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-enable</function>
+	  process &optional; timeout
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>process</term>
+	      <listitem>
+		<para>a lisp process (thread).</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>timeout</term>
+	      <listitem>
+		<para>a time interval in seconds.  May be any
+		non-negative real number the <function>floor</function> of
+		which fits in 32 bits.  The default is 1.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>undefined.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Tries to begin the execution of <varname>process</varname>.
+	  An error is signaled if <varname>process</varname> has never
+	  been <xref linkend=3D"f_process-preset"/>.  Otherwise,
+	  <varname>process</varname> invokes its initial function.
+	  </para>
+	  =

+	  <para><function>process-enable</function> attempts to
+	  synchronize with <varname>process</varname>, which is presumed
+	  to be reset or in the act of resetting itself.  If this attempt
+	  is not successful within the time interval specified by
+	  <varname>timeout</varname>, a continuable error is signaled,
+	  which offers the opportunity to continue waiting.
+	  </para>
+
+	  <para>A process cannot meaningfully attempt to enable itself.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-process"/></member>
+	    <member><xref linkend=3D"f_process-preset"/></member>
+	    <member><xref linkend=3D"f_process-run-function"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>It would be nice to have more discussion of what it means
+	  to synchronize with the process.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-run-function">
+	<indexterm zone=3D"f_process-run-function">
+	  <primary>process-run-function</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-RUN-FUNCTION</refname>
+	  <refpurpose>Creates a process, presets it, and enables it.
+	  </refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-run-function</function>
+	  process-specifier function &rest; args =3D> process</synopsis>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>process-specifier</term>
+	      <listitem>
+		<para>
+		  <varname>name</varname> | =

+		  (&key; <varname>name</varname>
+		  <varname>persistent</varname>
+		  <varname>priority</varname>
+		  <varname>class</varname>
+		  <varname>stack-size</varname>
+		  <varname>vstack-size</varname>
+		  <varname>tstack-size</varname>)
+		</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>name</term>
+	      <listitem>
+		<para>a string, used to identify the process.
+		Passed to <function>make-process</function>.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>function</term>
+	      <listitem>
+		<para>a function, designated by itself or by a symbol
+		which names it.  Passed to
+		<function>preset-process</function>.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>persistent</term>
+	      =

+	      <listitem>
+		<para>a boolean, passed to <function>make-process</function>.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	    =

+	    <varlistentry>
+	      <term>priority</term>
+	      =

+	      <listitem>
+		<para>ignored.</para>
+	      </listitem>
+	    </varlistentry>
+	    =

+	    <varlistentry>
+	      <term>class</term>
+	      =

+	      <listitem>
+		<para>a subclass of CCL:PROCESS.  Passed to
+		<function>make-process</function>.</para>
+	      </listitem>
+	    </varlistentry>
+	    =

+	    <varlistentry>
+	      <term>stack-size</term>
+	      =

+	      <listitem>
+		<para>a size, in bytes.  Passed to
+		<function>make-process</function>.</para>
+	      </listitem>
+	    </varlistentry>
+	    =

+	    <varlistentry>
+	      <term>vstack-size</term>
+	      =

+	      <listitem>
+		<para>a size, in bytes.  Passed to
+		<function>make-process</function>.</para>
+	      </listitem>
+	    </varlistentry>
+	    =

+	    <varlistentry>
+	      <term>tstack-size</term>
+	      =

+	      <listitem>
+		<para>a size, in bytes.  Passed to
+		<function>make-process</function>.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>process</term>
+	      <listitem>
+		<para>the newly-created process.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Creates a lisp process (thread) via
+	  <xref linkend=3D"f_make-process"/>,
+	  presets it via <xref linkend=3D"f_process-preset"/>, and
+	  enables it via <xref linkend=3D"f_process-enable"/>.  This means
+	  that <varname>process</varname> will immediately begin to
+	  execute.
+	  <function>process-run-function</function> is
+	  the simplest way to create and run a process.
+	  </para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-process"/></member>
+	    <member><xref linkend=3D"f_process-preset"/></member>
+	    <member><xref linkend=3D"f_process-enable"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-interrupt">
+	<indexterm zone=3D"f_process-interrupt">
+	  <primary>process-interrupt</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-INTERRUPT</refname>
+	  <refpurpose>Arranges for the target process to invoke a
+	  specified function at some point in the near future, and then
+	  return to what it was doing.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-interrupt</function>
+	  process function &rest; args =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>process</term>
+	      <listitem>
+		<para>a lisp process (thread).</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>function</term>
+	      <listitem>
+		<para>a function.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>args</term>
+	      <listitem>
+		<para>a list of values, appropriate as arguments to
+		<varname>function</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>the result of applying <varname>function</varname>
+		to <varname>args</varname> if <varname>proceess</varname>
+		is the <function>current-process</function>, otherwise
+		NIL.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Arranges for <varname>process</varname>
+	  to apply <varname>function</varname> to <varname>args</varname> at
+	  some point in the near future (interrupting whatever
+	  <varname>process</varname>
+	  was doing.) If <varname>function</varname> returns normally,
+	  <varname>process</varname> resumes
+	  execution at the point at which it was interrupted.</para>
+
+	  <para><varname>process</varname> must be in an enabled state in
+	  order to respond
+	  to a <function>process-interrupt</function> request.  It's
+	  perfectly legal for a process to call
+	  <function>process-interrupt</function> on itself.</para>
+
+	  <para><function>process-interrupt</function>
+	  uses asynchronous POSIX signals to interrupt threads. If the
+	  thread being interrupted is executing lisp code, it can
+	  respond to the interrupt almost immediately (as soon as it
+	  has finished pseudo-atomic operations like consing and
+	  stack-frame initialization.)</para>
+
+	  <para>If the interrupted thread is
+	  blocking in a system call, that system call is aborted by
+	  the signal and the interrupt is handled on return.
+	  </para>
+
+	  <para>It is
+	  still difficult to reliably interrupt arbitrary foreign code
+	  (that may be stateful or otherwise non-reentrant); the
+	  interrupt request is handled when such foreign code returns
+	  to or enters lisp.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"m_without-interrupts"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>It would probably be better for <varname>result</varname>
+	  to always be NIL, since the present behaviour is inconsistent.
+	  </para>
+
+	  <para>
+	    <function>Process-interrupt</function> works by sending signals
+	    between threads, via the C function
+	    <function>#_pthread_signal</function>.  It could be argued
+	    that it should be done in one of several possible other ways
+	    under
+	    Darwin, to make it practical to asynchronously interrupt
+	    things which make heavy use of the Mach nanokernel.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"v_current-process">
+	<indexterm zone=3D"v_current-process">
+	  <primary>*current-process*</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>*CURRENT-PROCESS*</refname>
+	  <refpurpose>Bound in each process, to that process
+	  itself.</refpurpose>
+	  <refclass>Variable</refclass>
+	</refnamediv>
+
+	<refsect1>
+	  <title>Value Type</title>
+
+	  <para>A lisp process (thread).</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Initial Value</title>
+	  =

+	  <para>Bound separately in each process, to that process itself.
+	  </para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Used when lisp code needs to find out what process it is
+	  executing in.  Shouldn't be set by user code.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_all-processes"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-reset">
+	<indexterm zone=3D"f_process-reset">
+	  <primary>process-reset</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-RESET</refname>
+	  <refpurpose>Causes a specified process to cleanly exit from
+	  any ongoing computation.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-reset</function>
+	  process &optional; kill-option =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>process</term>
+	      <listitem>
+		<para>a lisp process (thread).</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>kill-option</term>
+	      <listitem>
+		<para>a generalized boolean.  The default is T.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>undefined.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Causes <varname>process</varname> to cleanly exit
+	  from any ongoing computation.  If <varname>kill-option</varname>
+	  is true, <varname>process</varname> then exits.  Otherwise, it
+	  enters a state where it can be
+	  <xref linkend=3D"f_process-preset"/>. This
+	  is implemented by signaling a condition of type PROCESS-RESET;
+	  user-defined condition handlers should generally refrain from
+	  attempting to handle conditions of this type.</para>
+
+	  <para>A process can meaningfully reset itself.</para>
+
+	  <para>There is in general no way to know precisely when
+	  <varname>process</varname>
+	  has completed the act of resetting or killing itself; a process
+	  which has either entered the limbo of the reset state or exited
+	  has few ways of communicating either fact.
+	  <xref linkend=3D"f_process-enable"/>
+	  can reliably determine when a process has entered
+	  the "limbo of the reset state", but can't predict how long the
+	  clean exit from ongoing computation might take: that depends on
+	  the behavior of <function>unwind-protect</function> cleanup
+	  forms, and of the OS scheduler.</para>
+
+	  <para>Resetting a process other than
+	  <xref linkend=3D"v_current-process"/> involves the
+	  use of <xref linkend=3D"f_process-interrupt"/>.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_process-kill"/></member>
+	    <member><xref linkend=3D"f_process-abort"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-kill">
+	<indexterm zone=3D"f_process-kill">
+	  <primary>process-kill</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-KILL</refname>
+	  <refpurpose>Causes a specified process to cleanly exit from any
+	  ongoing computation, and then exit.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-kill</function> process
+	  =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>process</term>
+	      <listitem>
+		<para>a lisp process (thread).</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>undefined.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Entirely equivalent to calling
+	  (PROCESS-RESET PROCESS T).  Causes <varname>process</varname>
+	  to cleanly exit from any ongoing computation, and then exit.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	  =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_process-reset"/></member>
+	    <member><xref linkend=3D"f_process-abort"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-abort">
+	<indexterm zone=3D"f_process-abort">
+	  <primary>process-abort</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-ABORT</refname>
+	  <refpurpose>Causes a specified process to process an abort
+	  condition, as if it had invoked
+	  <function>abort</function>.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-abort</function> process
+	  &optional; condition
+	  =3D> NIL</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>process</term>
+	      <listitem>
+		<para>a lisp process (thread).</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>condition</term>
+	      <listitem>
+		<para>a lisp condition.  The default is NIL.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Entirely equivalent to calling
+	  (<xref linkend=3D"f_process-interrupt"/> <varname>process</varname>
+	  (<function>lambda</function> ()
+	  (<function>abort</function> <varname>condition</varname>))).
+	  Causes <varname>process</varname> to transfer control to the
+	  applicable handler or restart for <function>abort</function>.</para>
+
+	  <para>If <varname>condition</varname> is non-NIL,
+	  <function>process-abort</function> does not consider any
+	  handlers which are explicitly bound to conditions other than
+	  <varname>condition</varname>.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	  =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_process-reset"/></member>
+	    <member><xref linkend=3D"f_process-kill"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"v_ticks-per-second">
+	<indexterm zone=3D"v_ticks-per-second">
+	  <primary>*ticks-per-second*</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>*TICKS-PER-SECOND*</refname>
+	  <refpurpose>Bound to the clock resolution of the OS
+	  scheduler.</refpurpose>
+	  <refclass>Variable</refclass>
+	</refnamediv>
+
+	  <refsect1>
+	    <title>Value Type</title>
+
+	    <para>A positive integer.</para>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Initial Value</title>
+	    =

+	    <para>The clock resoluton of the OS scheduler.  Currently,
+	    both LinuxPPC and DarwinPPC yeild an initial value of 100.
+	    </para>
+	  </refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>This value is ordinarily of marginal interest at best,
+	  but, for backward compatibility, some functions accept timeout
+	  values expressed in "ticks".  This value gives the number of
+	  ticks per second.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_process-wait-with-timeout"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-whostate">
+	<indexterm zone=3D"f_process-whostate">
+	  <primary>process-whostate</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-WHOSTATE</refname>
+	  <refpurpose>Returns a string which describes the status of
+	  a specified process.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-whostate</function> process
+	  =3D> whostate</synopsis>
+	  <variablelist>
+	    <varlistentry>
+	      <term>process</term>
+	      <listitem>
+		<para>a lisp process (thread).</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>whostate</term>
+	      <listitem>
+		<para>a string which describes the "state" of
+		<varname>process</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>This information is primarily for the benefit of
+	  debugging tools.  <varname>whostate</varname> is a terse report
+	  on what <varname>process</varname> is doing, or not doing,
+	  and why.</para>
+
+	  <para>If the process is currently waiting in a call to
+	  <xref linkend=3D"f_process-wait"/> or
+	  <xref linkend=3D"f_process-wait-with-timeout"/>, its
+	  <function>process-whostate</function> will be the value
+	  which was passed to that function as <varname>whostate</varname>.
+	  </para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_process-wait"/></member>
+	    <member><xref linkend=3D"f_process-wait-with-timeout"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>This should arguably be SETFable, but doesn't seem to
+	  ever have been.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-allow-schedule">
+	<indexterm zone=3D"f_process-allow-schedule">
+	  <primary>process-allow-schedule</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-ALLOW-SCHEDULE</refname>
+	  <refpurpose>Used for cooperative multitasking; probably never
+	  necessary.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-allow-schedule</function></synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Advises the OS scheduler that the current thread has nothing
+	  useful to do and that it should try to find some other thread to
+	  schedule in its place. There's almost always a better
+	  alternative, such as waiting for some specific event to
+	  occur.  For example, you could use a lock or semaphore.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>This is a holdover from the days of cooperative
+	  multitasking.  All modern general-purpose operating systems use
+	  preemptive multitasking.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-wait">
+	<indexterm zone=3D"f_process-wait">
+	  <primary>process-wait</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-WAIT</refname>
+	  <refpurpose>Causes the current lisp process (thread) to wait for
+	  a given
+	  predicate to return true.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-wait</function>
+	  whostate function &rest; args =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>whostate</term>
+
+	      <listitem>
+		<para>a string, which will be the value of
+		<xref linkend=3D"f_process-whostate"/>
+		while the process is waiting.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>function</term>
+	      <listitem>
+		<para>a function, designated by itself or by a symbol
+		which names it.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>args</term>
+	      <listitem>
+		<para>a list of values, appropriate as arguments to
+		<varname>function</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>NIL.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Causes the current lisp process (thread) to repeatedly
+	  apply <varname>function</varname> to
+	  <varname>args</varname> until the call returns a true result, then
+	  returns NIL. After
+	  each failed call, yields the CPU as if by
+	  <xref linkend=3D"f_process-allow-schedule"/>.</para>
+	  =

+	  <para>
+	  As with <xref linkend=3D"f_process-allow-schedule"/>, it's almost
+	  always more efficient to wait for some
+	  specific event to occur; this isn't exactly busy-waiting, but
+	  the OS scheduler can do a better job of scheduling if it's given
+	  the relevant information.  For example, you could use a lock
+	  or semaphore.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_process-whostate"/></member>
+	    <member><xref linkend=3D"f_process-wait-with-timeout"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-wait-with-timeout">
+	<indexterm zone=3D"f_process-wait-with-timeout">
+	  <primary>process-wait-with-timeout</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-WAIT-WITH-TIMEOUT</refname>
+	  <refpurpose>Causes the current thread to wait for a given
+	  predicate to return true, or for a timeout to expire.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-wait-with-timeout</function>
+	  whostate ticks function args =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>whostate</term>
+	      <listitem>
+		<para>a string, which will be the value of
+		<xref linkend=3D"f_process-whostate"/>
+		while the process is waiting.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>ticks</term>
+	      <listitem>
+		<para>either a positive integer expressing a duration
+		in "ticks" (see <xref linkend=3D"v_ticks-per-second"/>),
+		or NIL.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>function</term>
+	      <listitem>
+		<para>a function, designated by itself or by a symbol
+		which names it.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>args</term>
+	      <listitem>
+		<para>a list of values, appropriate as arguments to
+		<varname>function</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>T if <function>process-wait-with-timeout</function>
+		returned because its <varname>function</varname> returned
+		true, or NIL if it returned because the duration
+		<varname>ticks</varname> has been exceeded.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>If <varname>ticks</varname> is NIL, behaves exactly like
+	  <xref linkend=3D"f_process-wait"/>, except for returning T.
+	  Otherwise, <varname>function</varname> will be tested repeatedly,
+	  in the same
+	  kind of test/yield loop as in <xref linkend=3D"f_process-wait"/>>
+	  until either <varname>function</varname> returns true,
+	  or the duration <varname>ticks</varname> has been exceeded.
+	  </para>
+
+	  <para> Having already read the descriptions of
+	  <xref linkend=3D"f_process-allow-schedule"/> and
+	  <xref linkend=3D"f_process-wait"/>, the
+	  astute reader has no doubt anticipated the observation that
+	  better alternatives should be used whenever possible.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"v_ticks-per-second"/></member>
+	    <member><xref linkend=3D"f_process-whostate"/></member>
+	    <member><xref linkend=3D"f_process-wait"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_without-interrupts">
+	<indexterm zone=3D"m_without-interrupts">
+	  <primary>without-interrupts</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>WITHOUT-INTERRUPTS</refname>
+	  <refpurpose>Evaluates its body in an environment in which
+	  process-interrupt requests are deferred.</refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>without-interrupts</function>
+	  &body; body =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>body</term>
+	      <listitem>
+		<para>an implicit progn.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>the primary value returned by
+		<varname>body</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Executes <varname>body</varname>
+	  in an environment in which <xref linkend=3D"f_process-interrupt"/>
+	  requests are
+	  deferred. As noted in the description of
+	  <xref linkend=3D"f_process-interrupt"/>, this has nothing to do
+	  with the
+	  scheduling of other threads; it may be necessary to inhibit
+	  <xref linkend=3D"f_process-interrupt"/> handling when
+	  (for instance) modifying some data
+	  structure (for which the current thread holds an appropriate lock)
+	  in some manner that&#39;s not reentrant.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_process-interrupt"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_make-lock">
+	<indexterm zone=3D"f_make-lock">
+	  <primary>make-lock</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>MAKE-LOCK</refname>
+	  <refpurpose>Creates and returns a lock object, which can
+	  be used for synchronization between threads.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>make-lock</function> &optional;
+	  name =3D> lock</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>name</term>
+	      <listitem>
+		<para>any lisp object; saved as part of
+		<varname>lock</varname>.  Typically a string or symbol
+		which may appear in the <xref linkend=3D"f_process-whostate"/>s
+		of threads which are waiting for <varname>lock</varname>.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>lock</term>
+	      <listitem>
+		<para>a newly-allocated object of type CCL:LOCK.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Creates and returns a lock object, which can
+	  be used to synchronize access to some shared resource.
+	  <varname>lock</varname> is
+	  initially in a &#34;free&#34; state; a lock can also be
+	  &#34;owned&#34; by a
+	  thread.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"m_with-lock-grabbed"/></member>
+	    <member><xref linkend=3D"f_grab-lock"/></member>
+	    <member><xref linkend=3D"f_release-lock"/></member>
+	    <member><xref linkend=3D"f_try-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_with-lock-grabbed">
+	<indexterm zone=3D"m_with-lock-grabbed">
+	  <primary>with-lock-grabbed</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>WITH-LOCK-GRABBED</refname>
+	  <refpurpose>Waits until a given lock can be obtained, then
+	  evaluates its body with the lock held.</refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>with-lock-grabbed</function>
+	  (lock) &body; body</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>lock</term>
+	      <listitem>
+		<para>an object of type CCL:LOCK.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>body</term>
+	      <listitem>
+		<para>an implicit progn.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>the primary value returned by
+		<varname>body</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Waits until <varname>lock</varname> is either free or
+	  owned by the calling
+	  thread, then excutes <varname>body</varname> with the
+	  lock owned by the calling thread. If <varname>lock</varname>
+	  was free when <function>with-lock-grabbed</function> was called,
+	  it is restored to a free state after <varname>body</varname>
+	  is executed.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_grab-lock"/></member>
+	    <member><xref linkend=3D"f_release-lock"/></member>
+	    <member><xref linkend=3D"f_try-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_grab-lock">
+	<indexterm zone=3D"f_grab-lock">
+	  <primary>grab-lock</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>GRAB-LOCK</refname>
+	  <refpurpose>Waits until a given lock can be obtained, then
+	  obtains it.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>grab-lock</function> lock</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>lock</term>
+	      <listitem>
+		<para>an object of type CCL:LOCK.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Blocks until <varname>lock</varname> is owned by the
+	  calling thread.</para>
+
+	  <para>The macro <xref linkend=3D"m_with-lock-grabbed"/>
+	  <emphasis>could</emphasis> be defined in
+	  terms of <function>grab-lock</function> and
+	  <xref linkend=3D"f_release-lock"/>, but it is actually
+	  implemented at a slightly lower level.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"m_with-lock-grabbed"/></member>
+	    <member><xref linkend=3D"f_release-lock"/></member>
+	    <member><xref linkend=3D"f_try-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_release-lock">
+	<indexterm zone=3D"f_release-lock">
+	  <primary>release-lock</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>RELEASE-LOCK</refname>
+	  <refpurpose>Relinquishes ownership of a given lock.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>release-lock</function> lock</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>lock</term>
+	      <listitem>
+		<para>an object of type CCL:LOCK.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Signals an error of type CCL:LOCK-NOT-OWNER if
+	  <varname>lock</varname>
+	  is not already owned by the calling thread; otherwise, undoes the
+	  effect of one previous =

+	  <xref linkend=3D"f_grab-lock"/>.  If this means that
+	  <function>release-lock</function> has now been called on
+	  <varname>lock</varname> the same number of times as
+	  <xref linkend=3D"f_grab-lock"/> has, <varname>lock</varname>
+	  becomes free.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"m_with-lock-grabbed"/></member>
+	    <member><xref linkend=3D"f_grab-lock"/></member>
+	    <member><xref linkend=3D"f_try-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_try-lock">
+	<indexterm zone=3D"f_try-lock">
+	  <primary>try-lock</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>TRY-LOCK</refname>
+	  <refpurpose>Obtains the given lock, but only if it is not
+	  necessary to wait for it.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>try-lock</function> lock =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>lock</term>
+	      <listitem>
+		<para>an object of type CCL:LOCK.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>T if <varname>lock</varname> has been obtained,
+		or NIL if it has not.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Tests whether <varname>lock</varname>
+	  can be obtained without blocking - that is, either
+	  <varname>lock</varname> is already free, or it is already owned
+	  by <xref linkend=3D"v_current-process"/>.  If it can,
+	  causes it to
+	  be owned by the calling lisp process (thread) and returns T.
+	  Otherwise, the lock
+	  is already owned by another thread and cannot be obtained without
+	  blocking; NIL is returned in this case.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"m_with-lock-grabbed"/></member>
+	    <member><xref linkend=3D"f_grab-lock"/></member>
+	    <member><xref linkend=3D"f_release-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_make-read-write-lock">
+	<indexterm zone=3D"f_make-read-write-lock">
+	  <primary>make-read-write-lock</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>MAKE-READ-WRITE-LOCK</refname>
+	  <refpurpose>Creates and returns a read-write lock, which can
+	  be used for synchronization between threads.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>make-read-write-lock</function>
+	  =3D> read-write-lock</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>read-write-lock</term>
+	      <listitem>
+		<para>a newly-allocated object of type
+		CCL:READ-WRITE-LOCK.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Creates and returns an object of type CCL::READ-WRITE-LOCK.
+	  A read-write lock may, at any given time, belong to any number
+	  of lisp processes (threads) which act as "readers"; or, it may
+	  belong to at most one process which acts as a "writer".  A
+	  read-write lock may never be held by a reader at the same time as
+	  a writer.  Intially, <varname>read-write-lock</varname> has
+	  no readers and no writers.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"m_with-read-lock"/></member>
+	    <member><xref linkend=3D"m_with-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>There probably should be some way to
+	  atomically &#34;promote&#34; a reader, making it a writer without
+	  releasing the lock, which could otherwise cause delay.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_with-read-lock">
+	<indexterm zone=3D"m_with-read-lock">
+	  <primary>with-read-lock</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>WITH-READ-LOCK</refname>
+	  <refpurpose>Waits until a given lock is available for
+	  read-only access, then evaluates its body with the lock
+	  held.</refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>with-read-lock</function>
+	  (read-write-lock) &body; body =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>read-write-lock</term>
+	      <listitem>
+		<para>an object of type
+		CCL:READ-WRITE-LOCK.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>body</term>
+	      <listitem>
+		<para>an implicit progn.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>the primary value returned by
+		<varname>body</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Waits until <varname>read-write-lock</varname> has no
+	  writer,
+	  ensures that <xref linkend=3D"v_current-process"/> is a
+	  reader of it, then executes <varname>body</varname>.
+	  </para>
+
+	  <para>After executing <varname>body</varname>, if
+	  <xref linkend=3D"v_current-process"/> was not a reader of
+	  <varname>read-write-lock</varname> before
+	  <function>with-read-lock</function> was called, the lock is
+	  released.  If it was already a reader, it remains one.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"m_with-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_with-write-lock">
+	<indexterm zone=3D"m_with-write-lock">
+	  <primary>with-write-lock</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>WITH-WRITE-LOCK</refname>
+	  <refpurpose>Waits until the given lock is available for write
+	  access, then executes its body with the lock held.</refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>with-write-lock</function>
+	  (read-write-lock) &body; body</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>read-write-lock</term>
+	      <listitem>
+		<para>an object of type
+		CCL:READ-WRITE-LOCK.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>body</term>
+	      <listitem>
+		<para>an implicit progn.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>the primary value returned by
+		<varname>body</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Waits until <varname>read-write-lock</varname> has no
+	  readers and no writer other than <xref linkend=3D"v_current-process"/>,
+	  then ensures that <xref linkend=3D"v_current-process"/> is the
+	  writer of it.  With the lock held, executes <varname>body</varname>.
+	  </para>
+
+	  <para>After executing <varname>body</varname>, if
+	  <xref linkend=3D"v_current-process"/> was not the writer of
+	  <varname>read-write-lock</varname> before
+	  <function>with-write-lock</function> was called, the lock is
+	  released.  If it was already the writer, it remains the
+	  writer.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"m_with-read-lock"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_make-semaphore">
+	<indexterm zone=3D"f_make-semaphore">
+	  <primary>make-semaphore</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>MAKE-SEMAPHORE</refname>
+	  <refpurpose>Creates and returns a semaphore, which can be used
+	  for synchronization between threads.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>make-semaphore</function>
+	  =3D> semaphore</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+	  =

+	  <variablelist>
+	    <varlistentry>
+	      <term>semaphore</term>
+	      <listitem>
+		<para>a newly-allocated object of type CCL:SEMAPHORE.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Creates and returns an object of type CCL:SEMAPHORE.
+	  A semaphore has an associated "count" which may be incremented
+	  and decremented atomically; incrementing it represents sending
+	  a signal, and decrementing it represents handling that signal.
+	  <varname>semaphore</varname> has an initial count of 0.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_signal-semaphore"/></member>
+	    <member><xref linkend=3D"f_wait-on-semaphore"/></member>
+	    <member><xref linkend=3D"f_timed-wait-on-semaphore"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_signal-semaphore">
+	<indexterm zone=3D"f_signal-semaphore">
+	  <primary>signal-semaphore</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>SIGNAL-SEMAPHORE</refname>
+	  <refpurpose>Atomically increments the count of a given
+	  semaphore.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>signal-semaphore</function>
+	  semaphore =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+	  =

+	  <variablelist>
+	    <varlistentry>
+	      <term>semaphore</term>
+	      <listitem>
+		<para>an object of type CCL:SEMAPHORE.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>an integer representing an error identifier
+		which was returned by the underlying OS call.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Atomically increments <varname>semaphore</varname>'s
+	  "count" by 1; this
+	  may enable a waiting thread to resume execution.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_wait-on-semaphore"/></member>
+	    <member><xref linkend=3D"f_timed-wait-on-semaphore"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para><varname>result</varname> should probably be interpreted
+	  and acted on by <function>signal-semaphore</function>, because
+	  it is not likely to be meaningful to a lisp program, and the
+	  most common cause of failure is a type error.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_wait-on-semaphore">
+	<indexterm zone=3D"f_wait-on-semaphore">
+	  <primary>wait-on-semaphore</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>WAIT-ON-SEMAPHORE</refname>
+	  <refpurpose>Waits until the given semaphore has a positive
+	  count which can be atomically decremented.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>wait-on-semaphore</function>
+	  semaphore =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+	  =

+	  <variablelist>
+	    <varlistentry>
+	      <term>semaphore</term>
+	      <listitem>
+		<para>an object of type CCL:SEMAPHORE.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>an integer representing an error identifier
+		which was returned by the underlying OS call.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Waits until <varname>semaphore</varname>
+	  has a positive count that can be
+	  atomically decremented; this will succeed exactly once for each
+	  corresponding call to SIGNAL-SEMAPHORE.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_signal-semaphore"/></member>
+	    <member><xref linkend=3D"f_timed-wait-on-semaphore"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para><varname>result</varname> should probably be interpreted
+	  and acted on by <function>wait-on-semaphore</function>, because
+	  it is not likely to be meaningful to a lisp program, and the
+	  most common cause of failure is a type error.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_timed-wait-on-semaphore">
+	<indexterm zone=3D"f_timed-wait-on-semaphore">
+	  <primary>timed-wait-on-semaphore</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>TIMED-WAIT-ON-SEMAPHORE</refname>
+	  <refpurpose>Waits until the given semaphore has a postive
+	  count which can be atomically decremented, or until a timeout
+	  expires.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>timed-wait-on-semaphore</function>
+	  semaphore timeout =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+	  =

+	  <variablelist>
+	    <varlistentry>
+	      <term>semaphore</term>
+	      <listitem>
+		<para>An object of type CCL:SEMAPHORE.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>timeout</term>
+	      <listitem>
+		<para>a time interval in seconds.  May be any
+		non-negative real number the <function>floor</function> of
+		which fits in 32 bits.  The default is 1.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>T if <function>timed-wait-on-semaphore</function>
+		returned because it was able to decrement the count of
+		<varname>semaphore</varname>; NIL if it returned because
+		the duration <varname>timeout</varname> has been
+		exceeded.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Waits until <varname>semaphore</varname>
+	  has a positive count that can be
+	  atomically decremented, or until the duration
+	  <varname>timeout</varname> has
+	  elapsed.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_wait-on-semaphore"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-input-wait">
+	<indexterm zone=3D"f_process-input-wait">
+	  <primary>process-input-wait</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-INPUT-WAIT</refname>
+	  <refpurpose>Waits until input is available on a given
+	  file-descriptor.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-input-wait</function>
+	  fd &optional; timeout</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+	  =

+	  <variablelist>
+	    <varlistentry>
+	      <term>fd</term>
+	      <listitem>
+		<para>a file descriptor, which is a non-negative integer
+		used by the OS to refer to an open file, socket, or similar
+		I/O connection.  See <xref linkend=3D"f_stream-device"/>.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>timeout</term>
+	      <listitem>
+		<para>either NIL, or a time interval in seconds.  May be any
+		non-negative real number the <function>floor</function> of
+		which fits in 32 bits.  The default is NIL.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Wait until input is available on <varname>fd</varname>.
+	  This uses the <function>select()</function> system call, and is
+	  generally a fairly
+	  efficient way of blocking while waiting for input. More
+	  accurately, <function>process-input-wait</function>
+	  waits until it&#39;s possible to read
+	  from fd without blocking, or until <varname>timeout</varname>, if
+	  it is not NIL, has been exceeded.</para>
+
+	  <para>
+	  Note that it&#39;s possible to read without blocking if
+	  the file is at its end - although, of course, the read will
+	  return zero bytes.</para>
+	</refsect1>
+	=

+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>
+	  <function>process-input-wait</function> has a timeout parameter,
+	  and
+	  <xref linkend=3D"f_process-output-wait"/> does not.  This
+	  inconsistency should probably be corrected.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_process-output-wait">
+	<indexterm zone=3D"f_process-output-wait">
+	  <primary>process-output-wait</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PROCESS-OUTPUT-WAIT</refname>
+	  <refpurpose>Waits until output is possible on a given file
+	  descriptor.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>process-output-wait</function> fd</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+	  =

+	  <variablelist>
+	    <varlistentry>
+	      <term>fd</term>
+	      <listitem>
+		<para>a file descriptor, which is a non-negative integer
+		used by the OS to refer to an open file, socket, or similar
+		I/O connection.  See <xref linkend=3D"f_stream-device"/>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Wait until output is possible on <varname>fd</varname>.
+	  This uses the <function>select()</function> system call, and is
+	  generally a fairly
+	  efficient way of blocking while waiting to output.</para>
+
+	  <para>If <function>process-output-wait</function> is called on
+	  a network socket which has not yet established a connection, it
+	  will wait until the connection is established.  This is an
+	  important use, often overlooked.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>
+	  <xref linkend=3D"f_process-input-wait"/> has a timeout parameter,
+	  and
+	  <function>process-output-wait</function> does not.  This
+	  inconsistency should probably be corrected.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_with-terminal-input">
+	<indexterm zone=3D"m_with-terminal-input">
+	  <primary>with-terminal-input</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>WITH-TERMINAL-INPUT</refname>
+	  <refpurpose>Executes its body in an environment with exclusive
+	  read access to the terminal.</refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>with-terminal-input</function>
+	  &body; body =3D> result</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+	  =

+	  <variablelist>
+	    <varlistentry>
+	      <term>body</term>
+	      <listitem>
+		<para>an implicit progn.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>result</term>
+	      <listitem>
+		<para>the primary value returned by
+		<varname>body</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Requests exclusive read access to the standard terminal
+	  stream, <varname>*terminal-io*</varname>.  Executes
+	  <varname>body</varname> in an environment with that access.
+	  </para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref
+	              linkend=3D"v_request-terminal-input-via-break"/></member>
+	    <member><xref linkend=3D"cmd_y"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"v_request-terminal-input-via-break">
+	<indexterm zone=3D"v_request-terminal-input-via-break">
+	  <primary>request-terminal-input-via-break</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>*REQUEST-TERMINAL-INPUT-VIA-BREAK*</refname>
+	  <refpurpose>Controls how attempts to obtain ownership of
+	  terminal input are made.</refpurpose>
+	  <refclass>Variable</refclass>
+	</refnamediv>
+
+	<refsect1>
+	  <title>Value Type</title>
+
+	  <para>A boolean.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Initial Value</title>
+	  =

+	  <para>NIL.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Controls how attempts to obtain ownership of terminal input
+	  are made. When NIL, a message is printed on *TERMINAL-IO*;
+	  it's expected that the user will later yield
+	  control of the terminal via the :Y toplevel command. When T, a
+	  BREAK condition is signaled in the owning process; continuing from
+	  the break loop will yield the terminal to the requesting process
+	  (unless the :Y command was already used to do so in the break
+	  loop.)</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	    <member><xref linkend=3D"cmd_y"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"cmd_y">
+	<indexterm zone=3D"cmd_y">
+	  <primary>:y</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>:Y</refname>
+	  <refpurpose>Yields control of terminal input to a specified
+	  lisp process (thread).</refpurpose>
+	  <refclass>Toplevel Command</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>(<function>:y</function> p)</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>p</term>
+	      <listitem>
+		<para>a lisp process (thread), designated either by
+		an integer which matches its
+		<function>process-serial-number</function>,
+		or by a string which is <function>equal</function> to
+		its <function>process-name</function>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>:Y is a toplevel command, not a function.  As such, it
+	  can only be used interactively, and only from the initial
+	  process.</para>
+
+	  <para>The command yields control of terminal input to the
+	  process <varname>p</varname>, which must have used
+	  <xref linkend=3D"m_with-terminal-input"/> to request access to the
+	  terminal input stream.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 =

+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"m_with-terminal-input"/></member>
+	    <member><xref
+	              linkend=3D"v_request-terminal-input-via-break"/></member>
+	    <member><xref linkend=3D"f_make-lock"/></member>
+	    <member><xref linkend=3D"f_make-read-write-lock"/></member>
+	    <member><xref linkend=3D"f_make-semaphore"/></member>
+	    <member><xref linkend=3D"f_process-input-wait"/></member>
+	    <member><xref linkend=3D"f_process-output-wait"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
     </sect1>
   </chapter>
 =

@@ -3132,7 +4387,9 @@
     <title>Programming with Sockets</title>
 =

     <sect1 id=3D"Sockets-Overview">
-      <para>OverviewOpenMCL supports the socket abstraction for
+      <title>Overview</title>
+
+      <para>OpenMCL supports the socket abstraction for
       interprocess communication. A socket represents a connection to
       another process, typically (but not necessarily) a TCP/IP
       network connection to a client or server running on some other
@@ -3143,629 +4400,1372 @@
       <para>OpenMCL supports three types of sockets: TCP sockets, UDP
       sockets, and Unix-domain sockets.  This should be enough for all
       but the most esoteric network situations.  All sockets are
-      created by .  The type of socket depends on the arguments to it,
-      as follows:</para>
-      <term><indexterm>tcp-stream
-          <variablelist>A buffered bi-directional stream over a TCP/IP con=
nection.tcp-stream is a subclass of stream, and you can read and write to i=
tusing all the usual stream functions. Created by (make-socket:addess-famil=
y :internet :type :stream :connect :active ...) or by(accept-connection ...=
).</variablelist>
-        </indexterm><indexterm>file-socket-stream
-          <variablelist>A buffered bi-directional stream over a "UNIX doma=
in"connection. file-socket-stream is a subclass of stream, and you canread =
and write to it using all the usual stream functions. Createdby (make-socke=
t :address-family :file :type :stream :connect :active...) or by (accept-co=
nnection ...),</variablelist>
-        </indexterm><indexterm>listener-socket
-          <variablelist>A passive socket used to listen for incoming TCP/I=
Pconnections on a particular port. A listener-socket is not a stream.It doe=
sn't support I/O. It can only be used to create newtcp-streams by accept-co=
nnection. Created by (make-socket :type:stream :connect :passive ...)</vari=
ablelist>
-        </indexterm><indexterm>file-listener-socket
-          <variablelist>A passive socket used to listen for incoming UNIX =
domainconnections named by a file in the local filesystem. Alistener-socket=
 is not a stream. It doesn't support I/O. It canonly be used to create new =
file-socket-streams by accept-connection.Created by (make-socket :address-f=
amily :file :type :stream :connect:passive ...)</variablelist>
-        </indexterm><indexterm>udp-socket
-          <variablelist>A socket representing a packet-based UDP/IP connec=
tion. Audp-socket supports I/O but it is not a stream. Instead, you mustuse=
 the special functions send-to and receive-from to read and writeto it. Cre=
ated by (make-socket :type :datagram ...)</variablelist>
-        </indexterm>
-      </term>
+      created by <xref linkend=3D"f_make-socket"/>.  The type of socket
+      depends on the arguments to it, as follows:</para>
+
+      <variablelist>
+	<varlistentry>
+	  <term>tcp-stream</term>
+
+	  <listitem>
+	    <para>A buffered bi-directional stream over a TCP/IP connection.
+	    tcp-stream is a subclass of stream, and you can read and write to it
+	    using all the usual stream functions. Created by (make-socket
+	    :addess-family :internet :type :stream :connect :active ...) or by
+	    (accept-connection ...).</para>
+	  </listitem>
+	</varlistentry>
+
+	<varlistentry>
+	  <term>file-socket-stream</term>
+
+	  <listitem>
+	    <para>A buffered bi-directional stream over a &#34;UNIX domain&#34;
+	    connection. file-socket-stream is a subclass of stream, and you can
+	    read and write to it using all the usual stream functions. Created
+	    by (make-socket :address-family :file :type :stream :connect :active
+	    ...) or by (accept-connection ...),</para>
+	  </listitem>
+	</varlistentry>
+
+	<varlistentry>
+	  <term>listener-socket</term>
+
+	  <listitem>
+	    <para>A passive socket used to listen for incoming TCP/IP
+	    connections on a particular port. A listener-socket is not a stream.
+	    It doesn&#39;t support I/O. It can only be used to create new
+	    tcp-streams by accept-connection. Created by (make-socket :type
+	    :stream :connect :passive ...)</para>
+	  </listitem>
+	</varlistentry>
+
+	<varlistentry>
+	  <term>file-listener-socket</term>
+
+	  <listitem>
+	    <para>A passive socket used to listen for incoming UNIX domain
+	    connections named by a file in the local filesystem. A
+	    listener-socket is not a stream. It doesn&#39;t support I/O. It can
+	    only be used to create new file-socket-streams by accept-connection.
+	    Created by (make-socket :address-family :file :type :stream :connect
+	    :passive ...)</para>
+	  </listitem>
+	</varlistentry>
+
+	<varlistentry>
+	  <term>udp-socket</term>
+
+	  <listitem>
+	    <para>A socket representing a packet-based UDP/IP connection. A
+	    udp-socket supports I/O but it is not a stream. Instead, you must
+	    use the special functions send-to and receive-from to read and write
+	    to it. Created by (make-socket :type :datagram ...)</para>
+	  </listitem>
+	</varlistentry>
+      </variablelist>
     </sect1>
 =

     <sect1 id=3D"Sockets-Dictionary">
       <title>Sockets Dictionary</title>
-
-      <sect2 id=3D"MAKE-SOCKET">
-        <para>MAKE-SOCKET</para>
-        <informalfigure>make-socket</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>MAKE-SOCKET &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-make-socket
-	  &amp;key address-family type connect eol format
+      <refentry id=3D"f_make-socket">
+	<indexterm zone=3D"f_make-socket">
+	  <primary>make-socket</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>MAKE-SOCKET</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>make-socket</function>
+	  &key; address-family type connect eol format
 	  remote-host remote-port local-host local-port local-filename
 	  remote-filename keepalive reuse-address nodelay broadcast linger
-	  backlog
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>address-family
-            <variablelist>The address/protocol family of this socket. Curr=
entlyonly :internet (the default), meaning IP, and :file,referring to UNIX =
domain addresses, are supported.</variablelist>
-          </indexterm><indexterm>type
-            <variablelist>One of :stream (the default) to request aconnect=
ion-oriented socket, or :datagram to request aconnectionless socket. The de=
fault is :stream.</variablelist>
-          </indexterm><indexterm>connect
-            <variablelist>This argument is only relevant to sockets of typ=
e:stream. One of :active (the default) to request a :passiveto request a fi=
le or TCP listener socket.</variablelist>
-          </indexterm><indexterm>eol
-            <variablelist>This argument is currently ignored (it is accept=
ed forcompatibility with Franz Allegro).</variablelist>
-          </indexterm><indexterm>format
-            <variablelist>One of :text (the default), :binary, or :bivalen=
t.This argument is ignored for :stream sockets for now, as:stream sockets a=
re currently always bivalent (i.e. theysupport both character and byte I/O)=
. For :datagram sockets,the format determines the type of buffer created by=
receive-from.</variablelist>
-          </indexterm><indexterm>remote-host
-            <variablelist>Required for TCP streams, it specifies the host =
toconnect to (in any format acceptable to lookup-hostname).Ignored for list=
ener sockets. For UDP sockets, it can beused to specify a default host for =
subsequent calls tosend-to or receive-from.</variablelist>
-          </indexterm><indexterm>remote-port
-            <variablelist>Required for TCP streams, it specifies the port =
toconnect to (in any format acceptable to lookup-port).Ignored for listener=
 sockets. For UDP sockets, it can beused to specify a default port for subs=
equent calls to forsubsequent calls to send-to or receive-from.</variableli=
st>
-          </indexterm><indexterm>remote-filename
-            <variablelist>Required for file-socket streams, it specifies t=
hename of a file in the local filesystem (e.g., NOT mountedvia NFS, AFP, SM=
B, ...) which names and controls access to aUNIX-domain socket.</variableli=
st>
-          </indexterm><indexterm>local-host
-            <variablelist>Allows you to specify a local host address for a=
listener or UDP socket, for the rare case where you want torestrict connect=
ions to those coming to a specific localaddress for security reasons.</vari=
ablelist>
-          </indexterm><indexterm>local-port
-            <variablelist>Specify a local port for a socket. Most useful f=
orlistener sockets, where it is the port on which the socketwill listen for=
 connections.</variablelist>
-          </indexterm><indexterm>local-filename
-            <variablelist>Required for file-listener-sockets. Specifies th=
e nameof a file in the local filesystem which is used to name aUNIX-domain =
socket. The actual filesystem file should notpreviously exist when the file=
-listener-socket is created;its parent directory should exist and be writab=
le by thecaller. The file used to name the socket will be deletedwhen the f=
ile-listener-socket is closed.</variablelist>
-          </indexterm><indexterm>keepalive
-            <variablelist>If true, enables the periodic transmission of"ke=
epalive" messages.</variablelist>
-          </indexterm><indexterm>reuse-address
-            <variablelist>If true, allows the reuse of local ports in list=
enersockets, overriding some TCP/IP protocol specifications. Youwill need t=
his if you are debugging a server..</variablelist>
-          </indexterm><indexterm>nodelay
-            <variablelist>If true, disables Nagle's algorithm, which tries=
to minimize TCP packet fragmentation by introducingtransmission delays in t=
he absence of replies. Try settingthis if you are using a protocol which in=
volves sending asteady stream of data with no replies and are seeingsignifi=
cant degradations in throughput.</variablelist>
-          </indexterm><indexterm>broadcast
-            <variablelist>If true, requests permission to broadcast datagr=
ams ona UDP socket.</variablelist>
-          </indexterm><indexterm>linger
-            <variablelist>If specified and non-nil, should be the number o=
fseconds the OS is allowed to wait for data to be pushedthrough when a clos=
e is done. Only relevant for TCP sockets.</variablelist>
-          </indexterm><indexterm>backlog
-            <variablelist>For a listener socket, specifies the number ofco=
nnections which can be pending but not accepted. Thedefault is 5, which is =
also the maximum on some operatingsystems.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Creates and returns a new socket</para>
-      </sect2>
-
-      <sect2 id=3D"ACCEPT-CONNECTION">
-        <para>ACCEPT-CONNECTION</para>
-        <informalfigure>accept-connection</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>ACCEPT-CONNECTION &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-accept-connection
-	  (socket listener-socket) &amp;key wait
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The listener-socket to listen on.</variablelist>
-          </indexterm><indexterm>wait
-            <variablelist>If true (the default), and there are no connecti=
onswaiting to be accepted, waits until one arrives. If false,returns NIL im=
mediately.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Extracts the first connection on the queue of pending
-connections, accepts it (i.e. completes the connection startup
-protocol) and returns a new tcp-stream or file-socket-stream
-representing the newly established connection. The tcp stream
-inherits any properties of the listener socket that are relevant
-(e.g. :keepalive, :nodelay, etc.) The original listener socket
-continues to be open listening for more connections, so you can
-call accept-connection on it again.</para>
-      </sect2>
-
-      <sect2 id=3D"DOTTED-TO-IPADDR">
-        <para>DOTTED-TO-IPADDR</para>
-        <informalfigure>dotted-to-ipaddr</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>DOTTED-TO-IPADDR &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-dotted-to-ipaddr
-	  dotted &amp;key errorp
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>dotted
-            <variablelist>A string representing an IP address in the"nn.nn=
.nn.nn" format</variablelist>
-          </indexterm><indexterm>errorp
-            <variablelist>If true (the default) an error is signaled if do=
ttedis invalid. If false, NIL is returned.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Converts a dotted-string representation of a host address to
-a 32-bit unsigned IP address.</para>
-      </sect2>
-
-      <sect2 id=3D"IPADDR-TO-DOTTED">
-        <para>IPADDR-TO-DOTTED</para>
-        <informalfigure>ipaddr-to-dotted</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>IPADDR-TO-DOTTED &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-ipaddr-to-dotted
-	  ipaddr &amp;key values
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>ipaddr
-            <variablelist>A 32-bit integer representing an internet host a=
ddress</variablelist>
-          </indexterm><indexterm>values
-            <variablelist>If false (the default), returns a string in the =
form"nn.nn.nn.nn". If true, returns four valuesrepresenting the four octets=
 of the address as unsigned8-bit integers.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Converts a 32-bit unsigned IP address into octets.</para>
-      </sect2>
-
-      <sect2 id=3D"IPADDR-TO-HOSTNAME">
-        <para>IPADDR-TO-HOSTNAME</para>
-        <informalfigure>ipaddr-to-hostname</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>IPADDR-TO-HOSTNAME &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-ipaddr-to-hostname
-	  ipaddr &amp;key ignore-cache
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>ipaddr
-            <variablelist>a 32-bit integer representing an internet host a=
ddress</variablelist>
-          </indexterm><indexterm>ignore-cache
-            <variablelist>This argument is ignored (it is accepted forcomp=
atibility with Franz Allegro)</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Converts a 32-bit unsigned IP address into a host name
-string</para>
-      </sect2>
-
-      <sect2 id=3D"LOOKUP-HOSTNAME">
-        <para>LOOKUP-HOSTNAME</para>
-        <informalfigure>lookup-hostname</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>LOOKUP-HOSTNAME &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-lookup-hostname
-	  host
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>host
-            <variablelist>Specifies the host. It can be either a host name=
string such as "clozure.com", or a dotted addressstring such as "192.168.0.=
1", or a 32-bit unsignedIP address such as 3232235521.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Converts a host spec in any of the acceptable formats into a
-32-bit unsigned IP address</para>
-      </sect2>
-
-      <sect2 id=3D"LOOKUP-PORT">
-        <para>LOOKUP-PORT</para>
-        <informalfigure>lookup-port</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>LOOKUP-PORT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-lookup-port
-	  port protocol
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>port
-            <variablelist>Specifies the port. It can be either a string, s=
uch as"http" or a symbol, such as :http, or an unsignedport number. Note th=
at a string is case-sensitive. A symbolis lowercased before lookup.</variab=
lelist>
-          </indexterm><indexterm>protocol
-            <variablelist>Must be one of "tcp" or "udp".</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Finds the port number for the specified port and protocol</p=
ara>
-      </sect2>
-
-      <sect2 id=3D"RECEIVE-FROM">
-        <para>RECEIVE-FROM</para>
-        <informalfigure>receive-from</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>RECEIVE-FROM &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-receive-from
-	  (socket udp-socket) size &amp;key buffer
-	  extract offset
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket to read from</variablelist>
-          </indexterm><indexterm>size
-            <variablelist>Maximum number of bytes to read. If the packet i=
slarger than this, any extra bytes are discarded.</variablelist>
-          </indexterm><indexterm>buffer
-            <variablelist>If specified, must be either a string or a byte =
vectorwhich will be used to read in the data. If not specified, anew buffer=
 will be created (of type determined bysocket-format).</variablelist>
-          </indexterm><indexterm>extract
-            <variablelist>If true, the subsequence of the buffer correspon=
dingonly to the data read in is extracted and returned as thefirst value. I=
f false (the default) the original buffer isreturned even if it is only par=
tially filled.</variablelist>
-          </indexterm><indexterm>offset
-            <variablelist>Specifies the start offset into the buffer at wh=
ichdata is to be stored. The default is 0.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Reads a UDP packet from a socket. If no packets are
-available, waits for a packet to arrive. Returns four values:</para>
-        <varlistentry numeration=3D"arabic">
-          <variablelist>The buffer with the data</variablelist>
-          <variablelist>The number of bytes read</variablelist>
-          <variablelist>The 32-bit unsigned IP address of the sender of th=
e data</variablelist>
-          <variablelist>The port number of the sender of the data</variabl=
elist>
-        </varlistentry>
-      </sect2>
-
-      <sect2 id=3D"SEND-TO">
-        <para>SEND-TO</para>
-        <informalfigure>send-to</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SEND-TO &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-send-to
-	  (socket udp-socket) buffer size &amp;key remote-host
-	  remote-port offset
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket to write to</variablelist>
-          </indexterm><indexterm>buffer
-            <variablelist>A vector containing the data to send. It must be=
either a string or a byte vector (either one is acceptableregardless of the=
 stream format).</variablelist>
-          </indexterm><indexterm>size
-            <variablelist>Number of bytes to send</variablelist>
-          </indexterm><indexterm>remote-host
-            <variablelist>The host to send the packet to, in any formatacc=
eptable to lookup-hostname. The default is the remotehost specified in the =
call to make-socket.</variablelist>
-          </indexterm><indexterm>remote-port
-            <variablelist>The port to send the packet to, in any formatacc=
eptable to lookup-port. The default is the remote portspecified in the call=
 to make-socket.</variablelist>
-          </indexterm><indexterm>offset
-            <variablelist>The offset in the buffer where the packet data s=
tarts</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Send a UDP packet over a socket.</para>
-      </sect2>
-
-      <sect2 id=3D"SHUTDOWN">
-        <para>SHUTDOWN</para>
-        <informalfigure>shutdown</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SHUTDOWN &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-shutdown
-	  socket &amp;key direction
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket to shut down (typically a tcp-stream)=
</variablelist>
-          </indexterm><indexterm>direction
-            <variablelist>One of :input to disallow further input, or :out=
put todisallow further output.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Shuts down part of a bidirectional connection. This is
-useful if e.g. you need to read responses after sending an
-end-of-file signal.</para>
-      </sect2>
-
-      <sect2 id=3D"SOCKET-OS-FD">
-        <para>SOCKET-OS-FD</para>
-        <informalfigure>socket-os-fd</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SOCKET-OS-FD &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-os-fd
-	  socket
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the native OS's representation of the socket, or
-NIL if the socket is closed. On Unix, this is the Unix 'file
-descriptor', a small non-negative integer. Note that it is
-rather dangerous to mess around with tcp-stream fd's, as there
-is all sorts of buffering and asynchronous I/O going on above the
-OS level. listener-socket and udp-socket fd's are safer to
-mess with directly as there is less magic going on.</para>
-      </sect2>
-
-      <sect2 id=3D"REMOTE-HOST">
-        <para>REMOTE-HOST</para>
-        <informalfigure>remote-host</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>REMOTE-HOST &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-remote-host
-	  socket
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the 32-bit unsigned IP address of the remote host,
-or NIL if the socket is not connected.</para>
-      </sect2>
-
-      <sect2 id=3D"REMOTE-PORT">
-        <para>REMOTE-PORT</para>
-        <informalfigure>remote-port</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>REMOTE-PORT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-remote-port
-	  socket
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the remote port number, or NIL if the socket is not
-connected.</para>
-      </sect2>
-
-      <sect2 id=3D"LOCAL-HOST">
-        <para>LOCAL-HOST</para>
-        <informalfigure>local-host</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>LOCAL-HOST &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-local-host
-	  socket
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns 32-bit unsigned IP address of the local host.</para>
-      </sect2>
-
-      <sect2 id=3D"LOCAL-PORT">
-        <para>LOCAL-PORT</para>
-        <informalfigure>local-port</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>LOCAL-PORT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-local-port
-	  socket
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the local port number</para>
-      </sect2>
-
-      <sect2 id=3D"SOCKET-ADDRESS-FAMILY">
-        <para>SOCKET-ADDRESS-FAMILY</para>
-        <informalfigure>socket-address-family</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SOCKET-ADDRESS-FAMILY &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-address-family
-	  socket
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns :internet or :file, as appropriate.</para>
-      </sect2>
-
-      <sect2 id=3D"SOCKET-CONNECT">
-        <para>SOCKET-CONNECT</para>
-        <informalfigure>socket-connect</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SOCKET-CONNECT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-connect
-	  socket
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns :active for tcp-stream, :passive for
-listener-socket, and NIL for udp-socket</para>
-      </sect2>
-
-      <sect2 id=3D"SOCKET-FORMAT">
-        <para>SOCKET-FORMAT</para>
-        <informalfigure>socket-format</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SOCKET-FORMAT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-format
-	  socket
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the socket format as specified by the :format
-argument to make-socket.</para>
-      </sect2>
-
-      <sect2 id=3D"SOCKET-TYPE">
-        <para>SOCKET-TYPE</para>
-        <informalfigure>socket-type</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SOCKET-TYPE &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-type
-	  socket
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>returns :stream for tcp-stream and listener-socket, and
-:datagram for udp-socket.</para>
-      </sect2>
-
-      <sect2 id=3D"SOCKET-ERROR">
-        <para>SOCKET-ERROR</para>
-        <informalfigure>socket-error</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SOCKET-ERROR &mdash;</para>
-        <para>Class</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>The class of OS errors signaled by socket functions</para>
-        <bridgehead renderas=3D"sect3">Superclasses</bridgehead>
-        <para>simple-error</para>
-      </sect2>
-
-      <sect2 id=3D"SOCKET-ERROR-CODE">
-        <para>SOCKET-ERROR-CODE</para>
-        <informalfigure>socket-error-code</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SOCKET-ERROR-CODE &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-error-code
-	  socket-error
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket-error
-            <variablelist>the condition</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>The OS error code of the error</para>
-      </sect2>
-
-      <sect2 id=3D"SOCKET-ERROR-IDENTIFIER">
-        <para>SOCKET-ERROR-IDENTIFIER</para>
-        <informalfigure>socket-error-identifier</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SOCKET-ERROR-IDENTIFIER &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-error-identifier
-	  socket-error
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket-error
-            <variablelist>the condition</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>A symbol representing the error code in a more
-OS-independent way.</para>
-        <para>One of: :address-in-use :connection-aborted :no-buffer-space
-:connection-timed-out :connection-refused :host-unreachable
-:host-down :network-down :address-not-available :network-reset
-:connection-reset :shutdown :access-denied or :unknown.</para>
-      </sect2>
-
-      <sect2 id=3D"SOCKET-ERROR-SITUATION">
-        <para>SOCKET-ERROR-SITUATION</para>
-        <informalfigure>socket-error-situation</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SOCKET-ERROR-SITUATION &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-error-situation
-	  socket-error
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket-error
-            <variablelist>the condition</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>A string describing the context where the error happened. On
-Linux, this is the name of the system call which returned the
-error.</para>
-      </sect2>
-
-      <sect2 id=3D"CLOSE">
-        <para>CLOSE</para>
-        <informalfigure>close</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CLOSE &mdash;</para>
-        <para>Method</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-close
-	  (socket socket) &amp;key abort
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket to close</variablelist>
-          </indexterm><indexterm>abort
-            <variablelist>If false (the default), closes the socket in ano=
rderly fashion, finishing up any buffered pending I/O,before closing the co=
nnection. If true, aborts/ignorespending I/O. (For listener and udp sockets=
, this argument iseffectively ignored since there is never any buffered I/O=
 toclean up).</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>The close generic function can be applied to sockets. It
-releases the operating system resources associated with the
-socket.</para>
-      </sect2>
-
-      <sect2 id=3D"WITH-OPEN-SOCKET">
-        <para>WITH-OPEN-SOCKET</para>
-        <informalfigure>with-open-socket</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>WITH-OPEN-SOCKET &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-with-open-socket
-	  (var . make-socket-args) &amp;body body
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>var
-            <variablelist>variable to bind</variablelist>
-          </indexterm><indexterm>make-socket-args
-            <variablelist>arguments suitable for passing to make-socket</v=
ariablelist>
-          </indexterm><indexterm>body
-            <variablelist>body to execute</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>executes body with var bound to the result of applying
-make-socket to make-socket-args. The socket gets closed on exit.</para>
-      </sect2>
+	  backlog</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>address-family</term>
+
+	      <listitem>
+		<para>The address/protocol family of this socket. Currently
+		only :internet (the default), meaning IP, and :file,
+		referring to UNIX domain addresses, are supported.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>type</term>
+
+	      <listitem>
+		<para>One of :stream (the default) to request a
+		connection-oriented socket, or :datagram to request a
+		connectionless socket. The default is :stream.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>connect</term>
+
+	      <listitem>
+		<para>This argument is only relevant to sockets of type
+		:stream. One of :active (the default) to request a :passive
+		to request a file or TCP listener socket.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>eol</term>
+
+	      <listitem>
+		<para>This argument is currently ignored (it is accepted for
+		compatibility with Franz Allegro).</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>format</term>
+
+	      <listitem>
+		<para>One of :text (the default), :binary, or :bivalent.
+		This argument is ignored for :stream sockets for now, as
+		:stream sockets are currently always bivalent (i.e. they
+		support both character and byte I/O). For :datagram sockets,
+		the format determines the type of buffer created by
+		receive-from.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>remote-host</term>
+
+	      <listitem>
+		<para>Required for TCP streams, it specifies the host to
+		connect to (in any format acceptable to lookup-hostname).
+		Ignored for listener sockets. For UDP sockets, it can be
+		used to specify a default host for subsequent calls to
+		send-to or receive-from.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>remote-port</term>
+
+	      <listitem>
+		<para>Required for TCP streams, it specifies the port to
+		connect to (in any format acceptable to lookup-port).
+		Ignored for listener sockets. For UDP sockets, it can be
+		used to specify a default port for subsequent calls to for
+		subsequent calls to send-to or receive-from.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>remote-filename</term>
+
+	      <listitem>
+		<para>Required for file-socket streams, it specifies the
+		name of a file in the local filesystem (e.g., NOT mounted
+		via NFS, AFP, SMB, ...) which names and controls access to a
+		UNIX-domain socket.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>local-host</term>
+
+	      <listitem>
+		<para>Allows you to specify a local host address for a
+		listener or UDP socket, for the rare case where you want to
+		restrict connections to those coming to a specific local
+		address for security reasons.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>local-port</term>
+
+	      <listitem>
+		<para>Specify a local port for a socket. Most useful for
+		listener sockets, where it is the port on which the socket
+		will listen for connections.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>local-filename</term>
+
+	      <listitem>
+		<para>Required for file-listener-sockets. Specifies the name
+		of a file in the local filesystem which is used to name a
+		UNIX-domain socket. The actual filesystem file should not
+		previously exist when the file-listener-socket is created;
+		its parent directory should exist and be writable by the
+		caller. The file used to name the socket will be deleted
+		when the file-listener-socket is closed.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>keepalive</term>
+
+	      <listitem>
+		<para>If true, enables the periodic transmission of
+		&#34;keepalive&#34; messages.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>reuse-address</term>
+
+	      <listitem>
+		<para>If true, allows the reuse of local ports in listener
+		sockets, overriding some TCP/IP protocol specifications. You
+		will need this if you are debugging a server..</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>nodelay</term>
+
+	      <listitem>
+		<para>If true, disables Nagle&#39;s algorithm, which tries
+		to minimize TCP packet fragmentation by introducing
+		transmission delays in the absence of replies. Try setting
+		this if you are using a protocol which involves sending a
+		steady stream of data with no replies and are seeing
+		significant degradations in throughput.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>broadcast</term>
+
+	      <listitem>
+		<para>If true, requests permission to broadcast datagrams on
+		a UDP socket.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>linger</term>
+
+	      <listitem>
+		<para>If specified and non-nil, should be the number of
+		seconds the OS is allowed to wait for data to be pushed
+		through when a close is done. Only relevant for TCP sockets.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>backlog</term>
+
+	      <listitem>
+		<para>For a listener socket, specifies the number of
+		connections which can be pending but not accepted. The
+		default is 5, which is also the maximum on some operating
+		systems.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Creates and returns a new socket</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_accept-connection">
+	<indexterm zone=3D"f_accept-connection">
+	  <primary>accept-connection</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>ACCEPT-CONNECTION</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>accept-connection</function>
+	  (socket listener-socket) &key; wait</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The listener-socket to listen on.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>wait</term>
+
+	      <listitem>
+		<para>If true (the default), and there are no connections
+		waiting to be accepted, waits until one arrives. If false,
+		returns NIL immediately.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Extracts the first connection on the queue of pending
+	  connections, accepts it (i.e. completes the connection startup
+	  protocol) and returns a new tcp-stream or file-socket-stream
+	  representing the newly established connection. The tcp stream
+	  inherits any properties of the listener socket that are relevant
+	  (e.g. :keepalive, :nodelay, etc.) The original listener socket
+	  continues to be open listening for more connections, so you can
+	  call accept-connection on it again.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_dotted-to-ipaddr">
+	<indexterm zone=3D"f_dotted-to-ipaddr">
+	  <primary>dotted-to-ipaddr</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>DOTTED-TO-IPADDR</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>dotted-to-ipaddr</function>
+	  dotted &key; errorp</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>dotted</term>
+
+	      <listitem>
+		<para>A string representing an IP address in the
+		&#34;nn.nn.nn.nn&#34; format</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>errorp</term>
+
+	      <listitem>
+		<para>If true (the default) an error is signaled if dotted
+		is invalid. If false, NIL is returned.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Converts a dotted-string representation of a host address to
+	  a 32-bit unsigned IP address.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_ipaddr-to-dotted">
+	<indexterm zone=3D"f_ipaddr-to-dotted">
+	  <primary>ipaddr-to-dotted</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>IPADDR-TO-DOTTED</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>ipaddr-to-dotted</function>
+	  ipaddr &key; values</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>ipaddr</term>
+
+	      <listitem>
+		<para>A 32-bit integer representing an internet host address</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>values</term>
+
+	      <listitem>
+		<para>If false (the default), returns a string in the form
+		&#34;nn.nn.nn.nn&#34;. If true, returns four values
+		representing the four octets of the address as unsigned
+		8-bit integers.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Converts a 32-bit unsigned IP address into octets.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_ipaddr-to-hostname">
+	<indexterm zone=3D"f_ipaddr-to-hostname">
+	  <primary>ipaddr-to-hostname</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>IPADDR-TO-HOSTNAME</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>ipaddr-to-hostname</function>
+	  ipaddr &key; ignore-cache</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>ipaddr</term>
+
+	      <listitem>
+		<para>a 32-bit integer representing an internet host address</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>ignore-cache</term>
+
+	      <listitem>
+		<para>This argument is ignored (it is accepted for
+		compatibility with Franz Allegro)</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Converts a 32-bit unsigned IP address into a host name
+	  string</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_lookup-hostname">
+	<indexterm zone=3D"f_lookup-hostname">
+	  <primary>lookup-hostname</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>LOOKUP-HOSTNAME</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>lookup-hostname</function>
+	  host</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>host</term>
+
+	      <listitem>
+		<para>Specifies the host. It can be either a host name
+		string such as &#34;clozure.com&#34;, or a dotted address
+		string such as &#34;192.168.0.1&#34;, or a 32-bit unsigned
+		IP address such as 3232235521.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Converts a host spec in any of the acceptable formats into a
+	  32-bit unsigned IP address</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_lookup-port">
+	<indexterm zone=3D"f_lookup-port">
+	  <primary>lookup-port</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>LOOKUP-PORT</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>lookup-port</function>
+	  port protocol</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>port</term>
+
+	      <listitem>
+		<para>Specifies the port. It can be either a string, such as
+		&#34;http&#34; or a symbol, such as :http, or an unsigned
+		port number. Note that a string is case-sensitive. A symbol
+		is lowercased before lookup.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>protocol</term>
+
+	      <listitem>
+		<para>Must be one of &#34;tcp&#34; or &#34;udp&#34;.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Finds the port number for the specified port and protocol</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_receive-from">
+	<indexterm zone=3D"f_receive-from">
+	  <primary>receive-from</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>RECEIVE-FROM</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>receive-from</function>
+	  (socket udp-socket) size &key; buffer
+	  extract offset</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket to read from</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>size</term>
+
+	      <listitem>
+		<para>Maximum number of bytes to read. If the packet is
+		larger than this, any extra bytes are discarded.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>buffer</term>
+
+	      <listitem>
+		<para>If specified, must be either a string or a byte vector
+		which will be used to read in the data. If not specified, a
+		new buffer will be created (of type determined by
+		socket-format).</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>extract</term>
+
+	      <listitem>
+		<para>If true, the subsequence of the buffer corresponding
+		only to the data read in is extracted and returned as the
+		first value. If false (the default) the original buffer is
+		returned even if it is only partially filled.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>offset</term>
+
+	      <listitem>
+		<para>Specifies the start offset into the buffer at which
+		data is to be stored. The default is 0.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Reads a UDP packet from a socket. If no packets are
+	  available, waits for a packet to arrive. Returns four values:</para>
+
+	  <orderedlist continuation=3D"restarts" inheritnum=3D"ignore">
+	    <listitem>
+	      <para>The buffer with the data</para>
+	    </listitem>
+
+	    <listitem>
+	      <para>The number of bytes read</para>
+	    </listitem>
+
+	    <listitem>
+	      <para>The 32-bit unsigned IP address of the sender of the data</par=
a>
+	    </listitem>
+
+	    <listitem>
+	      <para>The port number of the sender of the data</para>
+	    </listitem>
+	  </orderedlist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_send-to">
+	<indexterm zone=3D"f_send-to">
+	  <primary>send-to</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>SEND-TO</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>send-to</function>
+	  (socket udp-socket) buffer size &key; remote-host
+	  remote-port offset</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket to write to</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>buffer</term>
+
+	      <listitem>
+		<para>A vector containing the data to send. It must be
+		either a string or a byte vector (either one is acceptable
+		regardless of the stream format).</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>size</term>
+
+	      <listitem>
+		<para>Number of bytes to send</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>remote-host</term>
+
+	      <listitem>
+		<para>The host to send the packet to, in any format
+		acceptable to lookup-hostname. The default is the remote
+		host specified in the call to make-socket.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>remote-port</term>
+
+	      <listitem>
+		<para>The port to send the packet to, in any format
+		acceptable to lookup-port. The default is the remote port
+		specified in the call to make-socket.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>offset</term>
+
+	      <listitem>
+		<para>The offset in the buffer where the packet data starts</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Send a UDP packet over a socket.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_shutdown">
+	<indexterm zone=3D"f_shutdown">
+	  <primary>shutdown</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>SHUTDOWN</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>shutdown</function>
+	  socket &key; direction</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket to shut down (typically a tcp-stream)</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>direction</term>
+
+	      <listitem>
+		<para>One of :input to disallow further input, or :output to
+		disallow further output.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Shuts down part of a bidirectional connection. This is
+	  useful if e.g. you need to read responses after sending an
+	  end-of-file signal.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_socket-os-fd">
+	<indexterm zone=3D"f_socket-os-fd">
+	  <primary>socket-os-fd</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>SOCKET-OS-FD</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>socket-os-fd</function>
+	  socket</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns the native OS&#39;s representation of the socket, or
+	  NIL if the socket is closed. On Unix, this is the Unix &#39;file
+	  descriptor&#39;, a small non-negative integer. Note that it is
+	  rather dangerous to mess around with tcp-stream fd&#39;s, as there
+	  is all sorts of buffering and asynchronous I/O going on above the
+	  OS level. listener-socket and udp-socket fd&#39;s are safer to
+	  mess with directly as there is less magic going on.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_remote-host">
+	<indexterm zone=3D"f_remote-host">
+	  <primary>remote-host</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>REMOTE-HOST</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>remote-host</function>
+	  socket</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns the 32-bit unsigned IP address of the remote host,
+	  or NIL if the socket is not connected.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_remote-port">
+	<indexterm zone=3D"f_remote-port">
+	  <primary>remote-port</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>REMOTE-PORT</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>remote-port</function>
+	  socket</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns the remote port number, or NIL if the socket is not
+	  connected.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_local-host">
+	<indexterm zone=3D"f_local-host">
+	  <primary>local-host</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>LOCAL-HOST</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>local-host</function>
+	  socket</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns 32-bit unsigned IP address of the local host.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_local-port">
+	<indexterm zone=3D"f_local-port">
+	  <primary>local-port</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>LOCAL-PORT</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>local-port</function>
+	  socket</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns the local port number</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_socket-address-family">
+	<indexterm zone=3D"f_socket-address-family">
+	  <primary>socket-address-family</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>SOCKET-ADDRESS-FAMILY</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>socket-address-family</function>
+	  socket</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns :internet or :file, as appropriate.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_socket-connect">
+	<indexterm zone=3D"f_socket-connect">
+	  <primary>socket-connect</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>SOCKET-CONNECT</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>socket-connect</function>
+	  socket</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns :active for tcp-stream, :passive for
+	  listener-socket, and NIL for udp-socket</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_socket-format">
+	<indexterm zone=3D"f_socket-format">
+	  <primary>socket-format</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>SOCKET-FORMAT</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>socket-format</function>
+	  socket</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns the socket format as specified by the :format
+	  argument to make-socket.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_socket-type">
+	<indexterm zone=3D"f_socket-type">
+	  <primary>socket-type</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>SOCKET-TYPE</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>socket-type</function>
+	  socket</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>returns :stream for tcp-stream and listener-socket, and
+	  :datagram for udp-socket.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"c_socket-error">
+	<indexterm zone=3D"c_socket-error">
+	  <primary>socket-error</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>SOCKET-ERROR</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Class</refclass>
+	</refnamediv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>The class of OS errors signaled by socket functions</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Superclasses</title>
+
+	  <para>simple-error</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_socket-error-code">
+	<indexterm zone=3D"f_socket-error-code">
+	  <primary>socket-error-code</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>SOCKET-ERROR-CODE</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>socket-error-code</function>
+	  socket-error</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket-error</term>
+
+	      <listitem>
+		<para>the condition</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>The OS error code of the error</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_socket-error-identifier">
+	<indexterm zone=3D"f_socket-error-identifier">
+	  <primary>socket-error-identifier</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>SOCKET-ERROR-IDENTIFIER</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>socket-error-identifier</function>
+	  socket-error</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket-error</term>
+
+	      <listitem>
+		<para>the condition</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>A symbol representing the error code in a more
+	  OS-independent way.</para>
+
+	  <para>One of: :address-in-use :connection-aborted :no-buffer-space
+	  :connection-timed-out :connection-refused :host-unreachable
+	  :host-down :network-down :address-not-available :network-reset
+	  :connection-reset :shutdown :access-denied or :unknown.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_socket-error-situation">
+	<indexterm zone=3D"f_socket-error-situation">
+	  <primary>socket-error-situation</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>SOCKET-ERROR-SITUATION</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>socket-error-situation</function>
+	  socket-error</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket-error</term>
+
+	      <listitem>
+		<para>the condition</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>A string describing the context where the error happened. On
+	  Linux, this is the name of the system call which returned the
+	  error.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"o_close">
+	<indexterm zone=3D"o_close">
+	  <primary>close</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>CLOSE</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Method</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>close</function>
+	  (socket socket) &key; abort</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>socket</term>
+
+	      <listitem>
+		<para>The socket to close</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>abort</term>
+
+	      <listitem>
+		<para>If false (the default), closes the socket in an
+		orderly fashion, finishing up any buffered pending I/O,
+		before closing the connection. If true, aborts/ignores
+		pending I/O. (For listener and udp sockets, this argument is
+		effectively ignored since there is never any buffered I/O to
+		clean up).</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>The close generic function can be applied to sockets. It
+	  releases the operating system resources associated with the
+	  socket.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_with-open-socket">
+	<indexterm zone=3D"m_with-open-socket">
+	  <primary>with-open-socket</primary>
+	</indexterm>
+	<refnamediv>
+	  <refname>WITH-OPEN-SOCKET</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>with-open-socket</function>
+	  (var . make-socket-args) &body; body</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>var</term>
+
+	      <listitem>
+		<para>variable to bind</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>make-socket-args</term>
+
+	      <listitem>
+		<para>arguments suitable for passing to make-socket</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>body</term>
+
+	      <listitem>
+		<para>body to execute</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>executes body with var bound to the result of applying
+	  make-socket to make-socket-args. The socket gets closed on exit.</para>
+	</refsect1>
+      </refentry>
     </sect1>
   </chapter>
 =

@@ -3804,7 +5804,7 @@
     </sect1>
 =

     <sect1 id=3D"Limitations-and-known-bugs">
-      <para>Limitations and known bugs</para>
+      <title>Limitations and known bugs</title>
       <itemizedlist>
         <listitem><para>OpenMCL and the external processs may get
         confused about whoowns which streams when input, output, or
@@ -3820,199 +5820,423 @@
 =

     <sect1 id=3D"External-Program-Dictionary">
       <title>External-Program Dictionary</title>
-
-      <sect2 id=3D"RUN-PROGRAM">
-        <para>RUN-PROGRAM</para>
-        <informalfigure>run-program</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>RUN-PROGRAM &mdash; Invokes an external program as an OS sub=
process
-of lisp.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-run-program
-	    program args &amp;key (wait t) pty input
+	<refentry id=3D"f_run-program">
+	  <indexterm zone=3D"f_run-program">
+	    <primary>run-program</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>RUN-PROGRAM</refname>
+	    <refpurpose>Invokes an external program as an OS subprocess
+	    of lisp.</refpurpose>
+	    <refclass>Function</refclass>
+	  </refnamediv>
+
+	  <refsynopsisdiv>
+	    <synopsis><function>run-program</function>
+	    program args &key; (wait t) pty input
 	    if-input-does-not-exist output (if-output-exists :error) (error
-	    :output) (if-error-exists :error) status-hook
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>program
-            <variablelist>A string or pathname which denotes an executable=
 file.The PATH environment variable is used to find programs whosename does=
n't contain a directory component.</variablelist>
-          </indexterm><indexterm>args
-            <variablelist>A list of simple-strings</variablelist>
-          </indexterm><indexterm>wait
-            <variablelist>Indicates whether or not run-program should wait=
 forthe EXTERNAL-PROCESS to complete or should returnimmediately.</variable=
list>
-          </indexterm><indexterm>pty
-            <variablelist>This option is accepted but currently ignored;it=
's intended to make it easier to run external programsthat need to interact=
 with a terminal device.</variablelist>
-          </indexterm><indexterm>input
-            <variablelist>Selects the input source used by the EXTERNAL-PR=
OCESS.May be any of the following:
-              <listitem mark=3D"bullet">
-                <variablelist>NIL Specifies that a null input stream (e.g.=
,/dev/null) should be used.</variablelist>
-                <variablelist>T Specifies that the EXTERNAL-PROCESS should=
 usethe input source with which OpenMCL was invoked.</variablelist>
-                <variablelist>A string or pathname. Specifies that theEXTE=
RNAL-PROCESS should receive its input from the namedexisting file.</variabl=
elist>
-                <variablelist>:STREAM Creates a Lisp stream opened for cha=
racteroutput. Any data written to this stream (accessible asthe EXTERNAL-PR=
OCESS-INPUT-STREAM of theEXTERNAL-PROCESS object) appears as input to theex=
ternal process.</variablelist>
-                <variablelist>A stream. Specifies that the lisp stream sho=
uldprovide input to the EXTERNAL-PROCESS.</variablelist>
-              =

-              </listitem>
-</variablelist>
-          </indexterm><indexterm>if-input-does-not-exist
-            <variablelist>If the input argument specifies the name of anex=
isting file, this argument is used as theif-does-not-exist argument to OPEN=
 when that file is opened.</variablelist>
-          </indexterm><indexterm>output
-            <variablelist>Specifies where standard output from the externa=
lprocess should be sent. Analogous to input above.</variablelist>
-          </indexterm><indexterm>if-output-exists
-            <variablelist>If output is specified as a string or pathname, =
thisargument is used as the if-exists argument to OPEN when thatfile is ope=
ned.</variablelist>
-          </indexterm><indexterm>error
-            <variablelist>Specifies where error output from the external p=
rocessshould be sent. In addition to the values allowed foroutput, the keyw=
ord :OUTPUT can be used to indicate thaterror output should be sent where s=
tandard output goes.</variablelist>
-          </indexterm><indexterm>if-error-exists
-            <variablelist>Analogous to if-output-exists.</variablelist>
-          </indexterm><indexterm>status-hook
-            <variablelist>A user-defined function of one argument (theEXTE=
RNAL-PROCESS structure.) This function is calledwhenever OpenMCL detects a =
change in the staus of theEXTERNAL-PROCESS.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Runs the specified program in an external (Unix) process,
-returning an object of type EXTERNAL-PROCESS if successful.</para>
-      </sect2>
-
-      <sect2 id=3D"SIGNAL-EXTERNAL-PROCESS">
-        <para>SIGNAL-EXTERNAL-PROCESS</para>
-        <informalfigure>signal-external-process</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SIGNAL-EXTERNAL-PROCESS &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-signal-external-process
-	    proc signal-number
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>proc
-            <variablelist>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.=
</variablelist>
-          </indexterm><indexterm>signal
-            <variablelist>A small integer.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Sends the specified "signal" to the specified
-external process. (Typically, it would only be useful tocall
-this function if the EXTERNAL-PROCESS was created with :WAIT
-NIL. ) Returns T if successful; signals an error otherwise.</para>
-      </sect2>
-
-      <sect2 id=3D"EXTERNAL-PROCESS-ID">
-        <para>EXTERNAL-PROCESS-ID</para>
-        <informalfigure>external-process-id</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>EXTERNAL-PROCESS-ID &mdash; Returns the "process ID" of an O=
S subprocess,
-a positive integer which identifies it.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-external-process-id
-	    proc
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>proc
-            <variablelist>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.=
</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the <emphasis>process id</emphasis> assigned to
-the external process by the operating system. This is typically
-a positive, 16-bit number.</para>
-      </sect2>
-
-      <sect2 id=3D"EXTERNAL-PROCESS-INPUT-STREAM">
-        <para>EXTERNAL-PROCESS-INPUT-STREAM</para>
-        <informalfigure>external-process-input-stream</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>EXTERNAL-PROCESS-INPUT-STREAM &mdash; Returns the lisp strea=
m which is used to write
-input to a given OS subprocess, if it has one.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-external-process-input-stream
-	    proc
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>proc
-            <variablelist>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.=
</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the stream created when the input argument to
-run-program is specified as :STREAM.</para>
-      </sect2>
-
-      <sect2 id=3D"EXTERNAL-PROCESS-OUTPUT-STREAM">
-        <para>EXTERNAL-PROCESS-OUTPUT-STREAM</para>
-        <informalfigure>external-process-output-stream</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>EXTERNAL-PROCESS-OUTPUT-STREAM &mdash; Returns the lisp stre=
am which is used to read
-output from an OS subprocess, if there is one.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-external-process-output-stream
-	    proc
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>proc
-            <variablelist>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.=
</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the stream created when the output argument to
-run-program is specified as :STREAM.</para>
-      </sect2>
-
-      <sect2 id=3D"EXTERNAL-PROCESS-ERROR-STREAM">
-        <para>EXTERNAL-PROCESS-ERROR-STREAM</para>
-        <informalfigure>external-process-error-stream</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>EXTERNAL-PROCESS-ERROR-STREAM &mdash; Returns the stream whi=
ch is used to read
-"error" output from a given OS subprocess, if it has
-one.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-external-process-error-stream
-	    proc
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>proc
-            <variablelist>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.=
</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the stream created when the error argument to
-run-program is specified as :STREAM.</para>
-      </sect2>
-
-      <sect2 id=3D"EXTERNAL-PROCESS-STATUS">
-        <para>EXTERNAL-PROCESS-STATUS</para>
-        <informalfigure>external-process-status</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>EXTERNAL-PROCESS-STATUS &mdash; Returns information about wh=
ether an OS
-subprocess is running; or, if not, why not; and what its
-result code was if it completed.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-external-process-status
-	    proc
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>proc
-            <variablelist>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.=
</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns, as multiple values, a keyword denoting the status
-of the external process (one of :running, :stopped, :signaled, or
-:exited), and the exit code or terminating signal if the first
-value is other than :running.</para>
-      </sect2>
+	    :output) (if-error-exists :error) status-hook</synopsis>
+	  </refsynopsisdiv>
+
+	  <refsect1>
+	    <title>Arguments and Values</title>
+
+	    <variablelist>
+	      <varlistentry>
+		<term>program</term>
+
+		<listitem>
+		  <para>A string or pathname which denotes an executable file.
+		  The PATH environment variable is used to find programs whose
+		  name doesn't contain a directory component.</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>args</term>
+
+		<listitem>
+		  <para>A list of simple-strings</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>wait</term>
+
+		<listitem>
+		  <para>Indicates whether or not run-program should wait for
+		  the EXTERNAL-PROCESS to complete or should return
+		  immediately.</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>pty</term>
+
+		<listitem>
+		  <para>This option is accepted but currently ignored;
+		  it's intended to make it easier to run external programs
+		  that need to interact with a terminal device.</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>input</term>
+
+		<listitem>
+		  <para>Selects the input source used by the EXTERNAL-PROCESS.
+		  May be any of the following:</para>
+
+		  <itemizedlist>
+		    <listitem>
+		      <para>NIL Specifies that a null input stream (e.g.,
+		      /dev/null) should be used.</para>
+		    </listitem>
+
+		    <listitem>
+		      <para>T Specifies that the EXTERNAL-PROCESS should use
+		      the input source with which OpenMCL was invoked.</para>
+		    </listitem>
+
+		    <listitem>
+		      <para>A string or pathname. Specifies that the
+		      EXTERNAL-PROCESS should receive its input from the named
+		      existing file.</para>
+		    </listitem>
+
+		    <listitem>
+		      <para>:STREAM Creates a Lisp stream opened for character
+		      output. Any data written to this stream (accessible as
+		      the EXTERNAL-PROCESS-INPUT-STREAM of the
+		      EXTERNAL-PROCESS object) appears as input to the
+		      external process.</para>
+		    </listitem>
+
+		    <listitem>
+		      <para>A stream. Specifies that the lisp stream should
+		      provide input to the EXTERNAL-PROCESS.</para>
+		    </listitem>
+		  </itemizedlist>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>if-input-does-not-exist</term>
+
+		<listitem>
+		  <para>If the input argument specifies the name of an
+		  existing file, this argument is used as the
+		  if-does-not-exist argument to OPEN when that file is opened.</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>output</term>
+
+		<listitem>
+		  <para>Specifies where standard output from the external
+		  process should be sent. Analogous to input above.</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>if-output-exists</term>
+
+		<listitem>
+		  <para>If output is specified as a string or pathname, this
+		  argument is used as the if-exists argument to OPEN when that
+		  file is opened.</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>error</term>
+
+		<listitem>
+		  <para>Specifies where error output from the external process
+		  should be sent. In addition to the values allowed for
+		  output, the keyword :OUTPUT can be used to indicate that
+		  error output should be sent where standard output goes.</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>if-error-exists</term>
+
+		<listitem>
+		  <para>Analogous to if-output-exists.</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>status-hook</term>
+
+		<listitem>
+		  <para>A user-defined function of one argument (the
+		  EXTERNAL-PROCESS structure.) This function is called
+		  whenever OpenMCL detects a change in the staus of the
+		  EXTERNAL-PROCESS.</para>
+		</listitem>
+	      </varlistentry>
+	    </variablelist>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>Runs the specified program in an external (Unix) process,
+	    returning an object of type EXTERNAL-PROCESS if successful.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"f_signal-external-process">
+	  <indexterm zone=3D"f_signal-external-process">
+	    <primary>signal-external-process</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>SIGNAL-EXTERNAL-PROCESS</refname>
+	    <refpurpose></refpurpose>
+	    <refclass>Function</refclass>
+	  </refnamediv>
+
+	  <refsynopsisdiv>
+	    <synopsis><function>signal-external-process</function>
+	    proc signal-number</synopsis>
+	  </refsynopsisdiv>
+
+	  <refsect1>
+	    <title>Arguments and Values</title>
+
+	    <variablelist>
+	      <varlistentry>
+		<term>proc</term>
+
+		<listitem>
+		  <para>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>signal</term>
+
+		<listitem>
+		  <para>A small integer.</para>
+		</listitem>
+	      </varlistentry>
+	    </variablelist>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>Sends the specified "signal" to the specified
+	    external process. (Typically, it would only be useful tocall
+	    this function if the EXTERNAL-PROCESS was created with :WAIT
+	    NIL. ) Returns T if successful; signals an error otherwise.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"f_external-process-id">
+	  <indexterm zone=3D"f_external-process-id">
+	    <primary>external-process-id</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>EXTERNAL-PROCESS-ID</refname>
+	    <refpurpose>Returns the "process ID" of an OS subprocess,
+	    a positive integer which identifies it.</refpurpose>
+	    <refclass>Function</refclass>
+	  </refnamediv>
+
+	  <refsynopsisdiv>
+	    <synopsis><function>external-process-id</function>
+	    proc</synopsis>
+	  </refsynopsisdiv>
+
+	  <refsect1>
+	    <title>Arguments and Values</title>
+
+	    <variablelist>
+	      <varlistentry>
+		<term>proc</term>
+
+		<listitem>
+		  <para>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.</para>
+		</listitem>
+	      </varlistentry>
+	    </variablelist>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>Returns the <emphasis>process id</emphasis> assigned to
+	    the external process by the operating system. This is typically
+	    a positive, 16-bit number.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"f_external-process-input-stream">
+	  <indexterm zone=3D"f_external-process-input-stream">
+	    <primary>external-process-input-stream</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>EXTERNAL-PROCESS-INPUT-STREAM</refname>
+	    <refpurpose>Returns the lisp stream which is used to write
+	    input to a given OS subprocess, if it has one.</refpurpose>
+	    <refclass>Function</refclass>
+	  </refnamediv>
+
+	  <refsynopsisdiv>
+	    <synopsis><function>external-process-input-stream</function>
+	    proc</synopsis>
+	  </refsynopsisdiv>
+
+	  <refsect1>
+	    <title>Arguments and Values</title>
+
+	    <variablelist>
+	      <varlistentry>
+		<term>proc</term>
+
+		<listitem>
+		  <para>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.</para>
+		</listitem>
+	      </varlistentry>
+	    </variablelist>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>Returns the stream created when the input argument to
+	    run-program is specified as :STREAM.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"f_external-process-output-stream">
+	  <indexterm zone=3D"f_external-process-output-stream">
+	    <primary>external-process-output-stream</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>EXTERNAL-PROCESS-OUTPUT-STREAM</refname>
+	    <refpurpose>Returns the lisp stream which is used to read
+	    output from an OS subprocess, if there is one.</refpurpose>
+	    <refclass>Function</refclass>
+	  </refnamediv>
+
+	  <refsynopsisdiv>
+	    <synopsis><function>external-process-output-stream</function>
+	    proc</synopsis>
+	  </refsynopsisdiv>
+
+	  <refsect1>
+	    <title>Arguments and Values</title>
+
+	    <variablelist>
+	      <varlistentry>
+		<term>proc</term>
+
+		<listitem>
+		  <para>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.</para>
+		</listitem>
+	      </varlistentry>
+	    </variablelist>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>Returns the stream created when the output argument to
+	    run-program is specified as :STREAM.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"f_external-process-error-stream">
+	  <indexterm zone=3D"f_external-process-error-stream">
+	    <primary>external-process-error-stream</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>EXTERNAL-PROCESS-ERROR-STREAM</refname>
+	    <refpurpose>Returns the stream which is used to read
+	    "error" output from a given OS subprocess, if it has
+	    one.</refpurpose>
+	    <refclass>Function</refclass>
+	  </refnamediv>
+
+	  <refsynopsisdiv>
+	    <synopsis><function>external-process-error-stream</function>
+	    proc</synopsis>
+	  </refsynopsisdiv>
+
+	  <refsect1>
+	    <title>Arguments and Values</title>
+
+	    <variablelist>
+	      <varlistentry>
+		<term>proc</term>
+
+		<listitem>
+		  <para>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.</para>
+		</listitem>
+	      </varlistentry>
+	    </variablelist>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>Returns the stream created when the error argument to
+	    run-program is specified as :STREAM.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"f_external-process-status">
+	  <indexterm zone=3D"f_external-process-status">
+	    <primary>external-process-status</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>EXTERNAL-PROCESS-STATUS</refname>
+	    <refpurpose>Returns information about whether an OS
+	    subprocess is running; or, if not, why not; and what its
+	    result code was if it completed.</refpurpose>
+	    <refclass>Function</refclass>
+	  </refnamediv>
+
+	  <refsynopsisdiv>
+	    <synopsis><function>external-process-status</function>
+	    proc</synopsis>
+	  </refsynopsisdiv>
+
+	  <refsect1>
+	    <title>Arguments and Values</title>
+
+	    <variablelist>
+	      <varlistentry>
+		<term>proc</term>
+
+		<listitem>
+		  <para>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.</para>
+		</listitem>
+	      </varlistentry>
+	    </variablelist>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>Returns, as multiple values, a keyword denoting the status
+	    of the external process (one of :running, :stopped, :signaled, or
+	    :exited), and the exit code or terminating signal if the first
+	    value is other than :running.</para>
+	  </refsect1>
+	</refentry>
     </sect1>
   </chapter>
 =

@@ -4037,370 +6261,147 @@
       why standards are important.</para>
       <para>Here's a list of some classes which you might wish for
       your new stream class to inherit from:</para>
-      <colspec>
-        <thead cols=3D"1">
-          <tbody colwidth=3D"100*"></tbody>
-          <row>
-            <abstract>
-              <entry>fundamental-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>fundamental-input-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>fundamental-output-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>fundamental-character-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>fundamental-binary-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>fundamental-character-input-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>fundamental-character-output-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>fundamental-binary-input-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>fundamental-binary-output-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::buffered-stream-mixin</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::buffered-input-stream-mixin</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::buffered-output-stream-mixin</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::buffered-io-stream-mixin</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::buffered-character-input-stream-mixin</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::buffered-character-output-stream-mixin</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::buffered-character-io-stream-mixin</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::buffered-binary-input-stream-mixin</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::buffered-binary-output-stream-mixin</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::buffered-binary-io-stream-mixin</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>file-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>file-input-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>file-output-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>file-io-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>file-character-input-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>file-character-output-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>file-charcter-io-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>file-binary-input-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>file-binary-output-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>file-binary-io-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::fd-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::fd-input-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::fd-output-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::fd-io-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::fd-character-input-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::fd-character-output-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::fd-character-io-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::fd-binary-input-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::fd-binary-output-stream</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::fd-binary-io-stream</entry>
-            =

-            </abstract>
-          </row>
-        </thead>
-      </colspec>
-      <para>All of these are defined in ccl/level-1/l1-streams.lisp, excep=
t for
-the ccl:file-* ones, which are in ccl/level-1/l1-sysio.lisp.</para>
-      <para>According to the original Gray streams proposal, you should in=
herit
-from the most specific of the
-fundamental-* classes which applies.  Using OpenMCL, though, if you
-want
-buffering for better performance, which, unless you know of some
-reason you wouldn't, you do,
-you should instead inherit from the appropriate ccl::buffered-* class
-The buffering you get this way is exactly the same as the
-buffering which is used on ordinary, non-Gray streams, and force-output
-will work properly on it.</para>
-      <para>Notice that -mixin suffix in the names of all the ccl::buffere=
d-*
-classes?
-The suffix means that this class
-is not "complete"
-by itself; you still need to inherit from a fundamental-* stream,
-even if you also inherit from a *-mixin stream.  You might consider
-making your own class like this.  ....  Except that they do
-inherit from the fundamental-* streams, that's weird.</para>
-      <para>If you want to be able to create an instance of your class wit=
h the
-:class argument to (open) and (with-open-file), you should make it
-inherit from one of the file-* classes.  If you do this, it's not
-necessary to inherit from any of the other classes (though it won't
-hurt anything), since the file-* classes already do.</para>
+ =

+      <simplelist>
+	<member>fundamental-stream</member>
+	<member>fundamental-input-stream</member>
+	<member>fundamental-output-stream</member>
+	<member>fundamental-character-stream</member>
+	<member>fundamental-binary-stream</member>
+	<member>fundamental-character-input-stream</member>
+	<member>fundamental-character-output-stream</member>
+	<member>fundamental-binary-input-stream</member>
+	<member>fundamental-binary-output-stream</member>
+	<member>ccl::buffered-stream-mixin</member>
+	<member>ccl::buffered-input-stream-mixin</member>
+	<member>ccl::buffered-output-stream-mixin</member>
+	<member>ccl::buffered-io-stream-mixin</member>
+	<member>ccl::buffered-character-input-stream-mixin</member>
+	<member>ccl::buffered-character-output-stream-mixin</member>
+	<member>ccl::buffered-character-io-stream-mixin</member>
+	<member>ccl::buffered-binary-input-stream-mixin</member>
+	<member>ccl::buffered-binary-output-stream-mixin</member>
+	<member>ccl::buffered-binary-io-stream-mixin</member>
+	<member>file-stream</member>
+	<member>file-input-stream</member>
+	<member>file-output-stream</member>
+	<member>file-io-stream</member>
+	<member>file-character-input-stream</member>
+	<member>file-character-output-stream</member>
+	<member>file-charcter-io-stream</member>
+	<member>file-binary-input-stream</member>
+	<member>file-binary-output-stream</member>
+	<member>file-binary-io-stream</member>
+	<member>ccl::fd-stream</member>
+	<member>ccl::fd-input-stream</member>
+	<member>ccl::fd-output-stream</member>
+	<member>ccl::fd-io-stream</member>
+	<member>ccl::fd-character-input-stream</member>
+	<member>ccl::fd-character-output-stream</member>
+	<member>ccl::fd-character-io-stream</member>
+	<member>ccl::fd-binary-input-stream</member>
+	<member>ccl::fd-binary-output-stream</member>
+	<member>ccl::fd-binary-io-stream</member>
+      </simplelist>
+
+      <para>All of these are defined in ccl/level-1/l1-streams.lisp,
+      except for the ccl:file-* ones, which are in
+      ccl/level-1/l1-sysio.lisp.</para>
+      <para>According to the original Gray streams proposal, you
+      should inherit from the most specific of the fundamental-*
+      classes which applies.  Using OpenMCL, though, if you want
+      buffering for better performance, which, unless you know of some
+      reason you wouldn't, you do, you should instead inherit from the
+      appropriate ccl::buffered-* class The buffering you get this way
+      is exactly the same as the buffering which is used on ordinary,
+      non-Gray streams, and force-output will work properly on
+      it.</para>
+      <para>Notice that -mixin suffix in the names of all the
+      ccl::buffered-* classes?  The suffix means that this class is
+      not "complete" by itself; you still need to inherit from a
+      fundamental-* stream, even if you also inherit from a *-mixin
+      stream.  You might consider making your own class like this.
+      ....  Except that they do inherit from the fundamental-*
+      streams, that's weird.</para>
+      <para>If you want to be able to create an instance of your class
+      with the :class argument to (open) and (with-open-file), you
+      should make it inherit from one of the file-* classes.  If you
+      do this, it's not necessary to inherit from any of the other
+      classes (though it won't hurt anything), since the file-*
+      classes already do.</para>
       <para>When you inherit from the file-* classes, you can use
-(call-next-method) in any of your methods to get the standard
-behaviour.  This is especially useful if you want to create a class
-which performs some simple filtering operation, such
-as changing everything to uppercase or to a different character
-encoding.  If you do this, you will definitely need to specialize
-ccl::select-stream-class.  Your method on ccl::stream-select-class
-should accept an instance of the class, but pay no attention to its
-contents, and return a symbol naming the
-class to actually be instantiated.</para>
-      <para>If you need to make your functionality generic across all the
-different types of stream, probably the best way
-to implement it is to make it a mixin, define classes with all the
-variants of input, output, io, character, and binary, which inherit
-both from your mixin and from the appropriate other class, then
-define a method on ccl::select-stream-class which chooses from among
-those classes.</para>
-      <para>Note that some of these classes are internal
-to the CLL package.  If you try to inherit from those ones without
-the ccl:: prefix, you'll get an error which may confuse you, calling
-them "forward-referenced classes".  That just means you used the
-wrong symbol, so add the prefix.</para>
-      <para>Here's a list of some generic functions which you might wish to
-specialize for your new stream class, and which ought to be
-documented at some point.</para>
-      <colspec>
-        <thead cols=3D"1">
-          <tbody colwidth=3D"100*"></tbody>
-          <row>
-            <abstract>
-              <entry>stream-direction stream =3D></entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-device stream direction =3D></entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-length stream <literal>&amp;optional</literal>=
new =3D></entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-position stream <literal>&amp;optional</litera=
l>new =3D></entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>streamp stream =3D> boolean</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-write-char output-stream char =3D></entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-write-entire-string output-stream string =3D><=
/entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-read-char input-stream =3D></entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-unread-char input-stream char =3D></entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-force-output output-stream =3D> nil</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-maybe-force-output output-stream =3D> nil</ent=
ry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-finish-output output-stream =3D> nil</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-clear-output output-stream =3D> nil</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>close stream <literal>&amp;key</literal>abort =3D> bo=
olean</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-fresh-line stream =3D> t</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-line-length stream =3D> length</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>interactive-stream-p stream =3D> boolean</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-clear-input input-stream =3D> nil</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-listen input-stream =3D> boolean</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-filename stream =3D> string</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>ccl::select-stream-class instance in-p out-p char-p =
=3D>class</entry>
-            =

-            </abstract>
-          </row>
-        </thead>
-      </colspec>
+      (call-next-method) in any of your methods to get the standard
+      behaviour.  This is especially useful if you want to create a
+      class which performs some simple filtering operation, such as
+      changing everything to uppercase or to a different character
+      encoding.  If you do this, you will definitely need to
+      specialize ccl::select-stream-class.  Your method on
+      ccl::stream-select-class should accept an instance of the class,
+      but pay no attention to its contents, and return a symbol naming
+      the class to actually be instantiated.</para>
+      <para>If you need to make your functionality generic across all
+      the different types of stream, probably the best way to
+      implement it is to make it a mixin, define classes with all the
+      variants of input, output, io, character, and binary, which
+      inherit both from your mixin and from the appropriate other
+      class, then define a method on ccl::select-stream-class which
+      chooses from among those classes.</para>
+      <para>Note that some of these classes are internal to the CLL
+      package.  If you try to inherit from those ones without the
+      ccl:: prefix, you'll get an error which may confuse you, calling
+      them "forward-referenced classes".  That just means you used the
+      wrong symbol, so add the prefix.</para>
+      <para>Here's a list of some generic functions which you might
+      wish to specialize for your new stream class, and which ought to
+      be documented at some point.</para>
+      <simplelist>
+	<member>stream-direction stream =3D></member>
+	<member>stream-device stream direction =3D></member>
+	<member>stream-length stream &optional; new =3D></member>
+	<member>stream-position stream &optional; new =3D></member>
+	<member>streamp stream =3D> boolean</member>
+	<member>stream-write-char output-stream char =3D></member>
+	<member>stream-write-entire-string output-stream string =3D></member>
+	<member>stream-read-char input-stream =3D></member>
+	<member>stream-unread-char input-stream char =3D></member>
+	<member>stream-force-output output-stream =3D> nil</member>
+	<member>stream-maybe-force-output output-stream =3D> nil</member>
+	<member>stream-finish-output output-stream =3D> nil</member>
+	<member>stream-clear-output output-stream =3D> nil</member>
+	<member>close stream &key; abort =3D> boolean</member>
+	<member>stream-fresh-line stream =3D> t</member>
+	<member>stream-line-length stream =3D> length</member>
+	<member>interactive-stream-p stream =3D> boolean</member>
+	<member>stream-clear-input input-stream =3D> nil</member>
+	<member>stream-listen input-stream =3D> boolean</member>
+	<member>stream-filename stream =3D> string</member>
+	<member>ccl::select-stream-class instance in-p out-p char-p =3D>
+	        class</member>
+      </simplelist>
       <para>The following functions are standard parts of Common Lisp, but
 behave in special ways with regard to Gray streams.</para>
-      <colspec>
-        <thead cols=3D"1">
-          <tbody colwidth=3D"100*"></tbody>
-          <row>
-            <abstract>
-              <entry>open-stream-p stream =3D> generalized-boolean</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>input-stream-p stream =3D> generalized-boolean</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>output-stream-p stream =3D> generalized-boolean</entr=
y>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-element-type stream =3D></entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>stream-error-stream =3D></entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>open</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>close</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>with-open-file</entry>
-            =

-            </abstract>
-          </row>
-        </thead>
-      </colspec>
-      <para>Specifically, (open) and (with-open-file) accept a new keyword
-argument, :class, which may be a symbol naming a class; the class
-itself; or an instance of it.  The class so given must be a subtype
-of 'stream, and an instance of it with no particular contents will
-be passed to ccl::select-stream-class to determine what class to
-actually instantiate.</para>
-      <para>The following are standard, and do not behave specially with
-regard to Gray streams, but probably should.</para>
-      <colspec>
-        <thead cols=3D"1">
-          <tbody colwidth=3D"100*"></tbody>
-          <row>
-            <abstract>
-              <entry>stream-external-format</entry>
-            =

-            </abstract>
-          </row>
-        </thead>
-      </colspec>
+      <simplelist>
+	<member>open-stream-p stream =3D> generalized-boolean</member>
+	<member>input-stream-p stream =3D> generalized-boolean</member>
+	<member>output-stream-p stream =3D> generalized-boolean</member>
+	<member>stream-element-type stream =3D></member>
+	<member>stream-error-stream =3D></member>
+	<member>open</member>
+	<member>close</member>
+	<member>with-open-file</member>
+      </simplelist>
+
+      <para>Specifically, (open) and (with-open-file) accept a new
+      keyword argument, :class, which may be a symbol naming a class;
+      the class itself; or an instance of it.  The class so given must
+      be a subtype of 'stream, and an instance of it with no
+      particular contents will be passed to ccl::select-stream-class
+      to determine what class to actually instantiate.</para>
+      <para>The following are standard, and do not behave specially
+      with regard to Gray streams, but probably should.</para>
+       <simplelist>
+	<member>stream-external-format</member>
+      </simplelist>
     </sect1>
 =

     <sect1 id=3D"Extending-READ-SEQUENCE-and-WRITE-SEQUENCE">
@@ -4475,209 +6476,467 @@
 =

     <sect1 id=3D"Gray-Streams-Dictionary">
       <title>Gray Streams Dictionary</title>
-
-      <sect2 id=3D"CCL-STREAM-READ-LIST">
-        <para>CCL:STREAM-READ-LIST</para>
-        <informalfigure>stream-read-list</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL:STREAM-READ-LIST &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-read-list
-	  stream list count
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>stream
-            <variablelist>a stream, presumably a fundamental-input-stream.=
</variablelist>
-          </indexterm><indexterm>list
-            <variablelist>a list. When a STREAM-READ-LIST method is called=
 byREAD-SEQUENCE, this argument is guaranteed to be a properlist.</variable=
list>
-          </indexterm><indexterm>count
-            <variablelist>a non-negative integer. When a STREAM-READ-LIST =
methodis called by READ-SEQUENCE, this argument is guaranteed notto be grea=
ter than the length of the list.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Should try to read up to count elements from stream into the
-list list, returning the number of elements actually read (which
-may be less than count in case of a premature end-of-file.)</para>
-      </sect2>
-
-      <sect2 id=3D"CCL-STREAM-WRITE-LIST">
-        <para>CCL:STREAM-WRITE-LIST</para>
-        <informalfigure>stream-write-list</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL:STREAM-WRITE-LIST &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-write-list
-	  stream list count
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>stream
-            <variablelist>a stream, presumably a fundamental-ouput-stream.=
</variablelist>
-          </indexterm><indexterm>list
-            <variablelist>a list. When a STREAM-WRITE-LIST method is calle=
d byWRITE-SEQUENCE, this argument is guaranteed to be a properlist.</variab=
lelist>
-          </indexterm><indexterm>count
-            <variablelist>a non-negative integer. When a STREAM-WRITE-LIST=
method is called by WRITE-SEQUENCE, this argument isguaranteed not to be gr=
eater than the length of the list.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>should try to write the first count elements of list to
-stream. The return value of this method is ignored.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL-STREAM-READ-VECTOR">
-        <para>CCL:STREAM-READ-VECTOR</para>
-        <informalfigure>stream-read-vector</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL:STREAM-READ-VECTOR &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-read-vector
-	  stream vector start end
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>stream
-            <variablelist>a stream, presumably a fundamental-input-stream<=
/variablelist>
-          </indexterm><indexterm>vector
-            <variablelist>a vector. When a STREAM-READ-VECTOR method is ca=
lledby READ-SEQUENCE, this argument is guaranteed to be a simpleone-dimensi=
onal array.</variablelist>
-          </indexterm><indexterm>start
-            <variablelist>a non-negative integer. When a STREAM-READ-VECTO=
Rmethod is called by READ-SEQUENCE, this argument isguaranteed to be no gre=
ater than end and not greater thanthe length of vector.</variablelist>
-          </indexterm><indexterm>end
-            <variablelist>a non-negative integer. When a STREAM-READ-VECTO=
Rmethod is called by READ-SEQUENCE, this argument isguaranteed to be no les=
s than end and not greater than thelength of vector.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>should try to read successive elements from stream into
-vector, starting at element start (inclusive) and continuing
-through element end (exclusive.) Should return the index of the
-vector element beyond the last one stored into, which may be less
-than end in case of premature end-of-file.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL-STREAM-WRITE-VECTOR">
-        <para>CCL:STREAM-WRITE-VECTOR</para>
-        <informalfigure>stream-write-vector</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL:STREAM-WRITE-VECTOR &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-write-vector
-	  stream vector start end
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>stream
-            <variablelist>a stream, presumably a fundamental-output-stream=
</variablelist>
-          </indexterm><indexterm>vector
-            <variablelist>a vector. When a STREAM-WRITE-VECTOR method is c=
alledby WRITE-SEQUENCE, this argument is guaranteed to be asimple one-dimen=
sional array.</variablelist>
-          </indexterm><indexterm>start
-            <variablelist>a non-negative integer. When a STREAM-WRITE-VECT=
ORmethod is called by WRITE-SEQUENCE, this argument isguaranteed to be no g=
reater than end and not greater thanthe length of vector.</variablelist>
-          </indexterm><indexterm>end
-            <variablelist>a non-negative integer. When a STREAM-WRITE-VECT=
ORmethod is called by WRITE-SEQUENCE, this argument isguaranteed to be no l=
ess than end and not greater than thelength of vector.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>should try to write successive elements of vector to stream,
-starting at element start (inclusive) and continuing through
-element end (exclusive.)</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--STREAM-DEVICE">
-        <para>CCL::STREAM-DEVICE</para>
-        <informalfigure>stream-device</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::STREAM-DEVICE &mdash; Returns the OS file descriptor as=
sociated with a
-given lisp stream.</para>
-        <para>Generic Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-ccl::stream-device
-	  s direction
-</programlisting>
-        <bridgehead renderas=3D"sect3">Method Signatures</bridgehead>
-        <programlisting>
-ccl::stream-device
-	  (s stream) direction =3D> fd
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>s
-            <variablelist>a stream.</variablelist>
-          </indexterm><indexterm>direction
-            <variablelist>either :INPUT or :OUTPUT.</variablelist>
-          </indexterm><indexterm>fd
-            <variablelist>a file descriptor, which is a non-negative integ=
erused by the OS to refer to an open file, socket, or similarI/O connection=
.  NIL if there is no file descriptor associatedwith <literal>s</literal> i=
n the direction given by<literal>direction</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the file descriptor associated with
-<literal>s</literal> in the direction given by
-<literal>direction</literal>.  It is necessary to specify
-<literal>direction</literal> because the input and output
-file descriptors may be different; the most common case is when
-one of them has been redirected by the Unix shell.</para>
-      </sect2>
-
-      <sect2 id=3D"STREAM-READ-IVECTOR">
-        <para>STREAM-READ-IVECTOR</para>
-        <informalfigure>stream-read-ivector</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>STREAM-READ-IVECTOR &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-read-ivector
-	  stream ivector start-octet max-octets
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Reads up to max-octets octets from stream into ivector,
-storing them at start-octet. Returns the number of octets actually
-read.</para>
-        <bridgehead renderas=3D"sect3">Arguments</bridgehead>
-        <term><indexterm>stream
-            <variablelist>An input stream. The method defined onBUFFERED-I=
NPUT-STREAMs requires that the size in octets ofan instance of the stream's=
 element type is 1.</variablelist>
-          </indexterm><indexterm>ivector
-            <variablelist>Any ivector.</variablelist>
-          </indexterm><indexterm>start-octet
-            <variablelist>A non-negative integer.</variablelist>
-          </indexterm><indexterm>max-octets
-            <variablelist>A non-negative integer. The return value may be =
lessthan the value of this parameter if EOF was encountered.</variablelist>
-          </indexterm>
-        </term>
-      </sect2>
-
-      <sect2 id=3D"STREAM-WRITE-IVECTOR">
-        <para>STREAM-WRITE-IVECTOR</para>
-        <informalfigure>stream-write-ivector</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>STREAM-WRITE-IVECTOR &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-write-ivector stream
-	  ivector start-octet max-octets
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Writes max-octets octets to stream from ivector, starting at
-start-octet. Returns max-octets.</para>
-        <bridgehead renderas=3D"sect3">Arguments</bridgehead>
-        <term><indexterm>stream
-            <variablelist>An input stream. The method defined onBUFFERED-O=
UTPUT-STREAMs requires that the size in octets ofan instance of the stream'=
s element type is 1.</variablelist>
-          </indexterm><indexterm>ivector
-            <variablelist>Any ivector</variablelist>
-          </indexterm><indexterm>start-octet
-            <variablelist>A non-negative integer.</variablelist>
-          </indexterm><indexterm>max-octet
-            <variablelist>A non-negative integer.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Examples</bridgehead>
-        <programlisting>
-;;; Write the contents of a (SIMPLE-ARRAY(UNSIGNED-BYTE 16) 3)
+      <refentry id=3D"f_stream-read-list">
+	<indexterm zone=3D"f_stream-read-list">
+	  <primary>stream-read-list</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL:STREAM-READ-LIST</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Generic Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>stream-read-list</function>
+	  stream list count</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>stream</term>
+
+	      <listitem>
+		<para>a stream, presumably a fundamental-input-stream.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>list</term>
+
+	      <listitem>
+		<para>a list. When a STREAM-READ-LIST method is called by
+		READ-SEQUENCE, this argument is guaranteed to be a proper
+		list.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>count</term>
+
+	      <listitem>
+		<para>a non-negative integer. When a STREAM-READ-LIST method
+		is called by READ-SEQUENCE, this argument is guaranteed not
+		to be greater than the length of the list.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Should try to read up to count elements from stream into the
+	  list list, returning the number of elements actually read (which
+	  may be less than count in case of a premature end-of-file.)</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_stream-write-list">
+	<indexterm zone=3D"f_stream-write-list">
+	  <primary>stream-write-list</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL:STREAM-WRITE-LIST</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Generic Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>stream-write-list</function>
+	  stream list count</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>stream</term>
+
+	      <listitem>
+		<para>a stream, presumably a fundamental-ouput-stream.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>list</term>
+
+	      <listitem>
+		<para>a list. When a STREAM-WRITE-LIST method is called by
+		WRITE-SEQUENCE, this argument is guaranteed to be a proper
+		list.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>count</term>
+
+	      <listitem>
+		<para>a non-negative integer. When a STREAM-WRITE-LIST
+		method is called by WRITE-SEQUENCE, this argument is
+		guaranteed not to be greater than the length of the list.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>should try to write the first count elements of list to
+	  stream. The return value of this method is ignored.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_stream-read-vector">
+	<indexterm zone=3D"f_stream-read-vector">
+	  <primary>stream-read-vector</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL:STREAM-READ-VECTOR</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Generic Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>stream-read-vector</function>
+	  stream vector start end</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>stream</term>
+
+	      <listitem>
+		<para>a stream, presumably a fundamental-input-stream</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>vector</term>
+
+	      <listitem>
+		<para>a vector. When a STREAM-READ-VECTOR method is called
+		by READ-SEQUENCE, this argument is guaranteed to be a simple
+		one-dimensional array.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>start</term>
+
+	      <listitem>
+		<para>a non-negative integer. When a STREAM-READ-VECTOR
+		method is called by READ-SEQUENCE, this argument is
+		guaranteed to be no greater than end and not greater than
+		the length of vector.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>end</term>
+
+	      <listitem>
+		<para>a non-negative integer. When a STREAM-READ-VECTOR
+		method is called by READ-SEQUENCE, this argument is
+		guaranteed to be no less than end and not greater than the
+		length of vector.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>should try to read successive elements from stream into
+	  vector, starting at element start (inclusive) and continuing
+	  through element end (exclusive.) Should return the index of the
+	  vector element beyond the last one stored into, which may be less
+	  than end in case of premature end-of-file.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_stream-write-vector">
+	<indexterm zone=3D"f_stream-write-vector">
+	  <primary>stream-write-vector</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL:STREAM-WRITE-VECTOR</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Generic Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>stream-write-vector</function>
+	  stream vector start end</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>stream</term>
+
+	      <listitem>
+		<para>a stream, presumably a fundamental-output-stream</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>vector</term>
+
+	      <listitem>
+		<para>a vector. When a STREAM-WRITE-VECTOR method is called
+		by WRITE-SEQUENCE, this argument is guaranteed to be a
+		simple one-dimensional array.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>start</term>
+
+	      <listitem>
+		<para>a non-negative integer. When a STREAM-WRITE-VECTOR
+		method is called by WRITE-SEQUENCE, this argument is
+		guaranteed to be no greater than end and not greater than
+		the length of vector.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>end</term>
+
+	      <listitem>
+		<para>a non-negative integer. When a STREAM-WRITE-VECTOR
+		method is called by WRITE-SEQUENCE, this argument is
+		guaranteed to be no less than end and not greater than the
+		length of vector.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>should try to write successive elements of vector to stream,
+	  starting at element start (inclusive) and continuing through
+	  element end (exclusive.)</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_stream-device">
+	<indexterm zone=3D"f_stream-device">
+	  <primary>stream-device</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::STREAM-DEVICE</refname>
+	  <refpurpose>Returns the OS file descriptor associated with a
+	  given lisp stream.</refpurpose>
+	  <refclass>Generic Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>ccl::stream-device</function>
+	  s direction</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Method Signatures</title>
+
+	  <synopsis><function>ccl::stream-device</function>
+	  (s stream) direction =3D> fd</synopsis>
+	</refsect1>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+	  =

+	  <variablelist>
+	    <varlistentry>
+	      <term>s</term>
+	      <listitem>
+		<para>a stream.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>direction</term>
+	      <listitem>
+		<para>either :INPUT or :OUTPUT.</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>fd</term>
+	      <listitem>
+		<para>a file descriptor, which is a non-negative integer
+		used by the OS to refer to an open file, socket, or similar
+		I/O connection.  NIL if there is no file descriptor associated
+		with <varname>s</varname> in the direction given by
+		<varname>direction</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns the file descriptor associated with
+	  <varname>s</varname> in the direction given by
+	  <varname>direction</varname>.  It is necessary to specify
+	  <varname>direction</varname> because the input and output
+	  file descriptors may be different; the most common case is when
+	  one of them has been redirected by the Unix shell.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_stream-read-ivector">
+	<indexterm zone=3D"f_stream-read-ivector">
+	  <primary>stream-read-ivector</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>STREAM-READ-IVECTOR</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Generic Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>stream-read-ivector</function>
+	  stream ivector start-octet max-octets</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Reads up to max-octets octets from stream into ivector,
+	  storing them at start-octet. Returns the number of octets actually
+	  read.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Arguments</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>stream</term>
+
+	      <listitem>
+		<para>An input stream. The method defined on
+		BUFFERED-INPUT-STREAMs requires that the size in octets of
+		an instance of the stream's element type is 1.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>ivector</term>
+
+	      <listitem>
+		<para>Any ivector.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>start-octet</term>
+
+	      <listitem>
+		<para>A non-negative integer.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>max-octets</term>
+
+	      <listitem>
+		<para>A non-negative integer. The return value may be less
+		than the value of this parameter if EOF was encountered.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_stream-write-ivector">
+	<indexterm zone=3D"f_stream-write-ivector">
+	  <primary>stream-write-ivector</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>STREAM-WRITE-IVECTOR</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Generic Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>stream-write-ivector stream</function>
+	  ivector start-octet max-octets</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Writes max-octets octets to stream from ivector, starting at
+	  start-octet. Returns max-octets.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Arguments</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>stream</term>
+
+	      <listitem>
+		<para>An input stream. The method defined on
+		BUFFERED-OUTPUT-STREAMs requires that the size in octets of
+		an instance of the stream's element type is 1.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>ivector</term>
+
+	      <listitem>
+		<para>Any ivector</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>start-octet</term>
+
+	      <listitem>
+		<para>A non-negative integer.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>max-octet</term>
+
+	      <listitem>
+		<para>A non-negative integer.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Examples</title>
+
+<programlisting format=3D"linespecific">;;; Write the contents of a (SIMPL=
E-ARRAY(UNSIGNED-BYTE 16) 3) =

 ;;; to a character file stream. Read back the characters.
-(let* ((a (make-array 3
+(let* ((a (make-array 3 =

                      :element-type '(unsigned-byte 16)
                      :initial-contents '(26725 27756 28449))))
   (with-open-file (s "junk"
@@ -4692,20 +6951,20 @@
     (read-line s)))
 =

 ;;; Write a vector of DOUBLE-FLOATs. Note that (to maintain
-;;; alignment) there are 4 octets of padding before the 0th
-;;; element of a (VECTOR DOUBLE-FLOAT) in 32-bit OpenMCL.
-;;; (Note that (=3D (- ppc32::misc-dfloat-offset
-;;;                  ppc32::misc-data-offset) 4))
+;;; alignment) there are 4 octets of padding before the 0th =

+;;; element of a (VECTOR DOUBLE-FLOAT).
+;;; (Note that (=3D (- arch::misc-dfloat-offset =

+;;;                  arch::misc-data-offset) 4))
 (defun write-double-float-vector
-  (stream vector &amp;key (start 0) (end (length vector)))
+  (stream vector &#38;key (start 0) (end (length vector)))
   (check-type vector (vector double-float))
-  (let* ((start-octet (+ (* start 8)
-                         (- target::misc-dfloat-offset
-                         target::misc-data-offset)))
+  (let* ((start-octet (+ (* start 8) =

+                         (- arch::misc-dfloat-offset
+                         arch::misc-data-offset)))
          (num-octets (* 8 (- end start))))
-    (stream-write-ivector stream vector start-octet num-octets)))
-</programlisting>
-      </sect2>
+    (stream-write-ivector stream vector start-octet num-octets)))</program=
listing>
+	</refsect1>
+      </refentry>
     </sect1>
   </chapter>
 =

@@ -5270,7 +7529,7 @@
 =

 	      <listitem>
 		<para>The argument/return values
-		is <link linkend=3D"arb24">a MACPTR</link>.</para>
+		is <link linkend=3D""Referencing-and-Using-Foreign-Memory-Addresses">a M=
ACPTR</link>.</para>
 	      </listitem>
 	    </varlistentry>
 =

@@ -5615,258 +7874,677 @@
         </sect3>
 =

         <sect3 id=3D"iget-bit--Function-">
-          <para>%get-bit [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>%get-bit ptr bit-offset</variablelist>
-            </indexterm><indexterm>Description
-              <variablelist>References and returns the bit-offsetth bit at=
 the addressencapsulated by ptr. (Bit 0 at a given address is the mostsigni=
ficant bit of the byte at that address.) Can be used withSETF.</variablelis=
t>
-            </indexterm><indexterm>Arguments
-              <variablelist> =

-                <term><indexterm>ptr
-                    <variablelist>A MACPTR</variablelist>
-                  </indexterm><indexterm>bit-offset
-                    <variablelist>A fixnum</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
+	  <title>%get-bit [Function]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%get-bit ptr bit-offset</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>References and returns the bit-offsetth bit at the address
+		encapsulated by ptr. (Bit 0 at a given address is the most
+		significant bit of the byte at that address.) Can be used with
+		SETF.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para>&#x00A0;</para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>ptr</term>
+
+		    <listitem>
+		      <para>A MACPTR</para>
+		    </listitem>
+		  </varlistentry>
+
+		  <varlistentry>
+		    <term>bit-offset</term>
+
+		    <listitem>
+		      <para>A fixnum</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
         </sect3>
 =

         <sect3 id=3D"iget-bitfield--Function-">
-          <para>%get-bitfield [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>%get-bitfield ptr bit-offset width</variableli=
st>
-            </indexterm><indexterm>Description
-              <variablelist>References and returns an unsigned integer com=
posed from thewidth bits found bit-offsetbits from the address encapsulated=
 byptr. (The least significant bit of the result is the value of(%get-bit p=
tr (1- (+ bit-offset width)))). Can be used with SETF.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> </variablelist>
-            </indexterm><indexterm>ptr
-              <variablelist>A MACPTR
-                <term><indexterm>bit-offset
-                    <variablelist>A fixnum</variablelist>
-                  </indexterm><indexterm>width
-                    <variablelist>A positive fixnum</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
+          <title>%get-bitfield [Function]</title>
+ 	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%get-bitfield ptr bit-offset width</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>References and returns an unsigned integer composed from the
+		width bits found bit-offsetbits from the address encapsulated by
+		ptr. (The least significant bit of the result is the value of
+		(%get-bit ptr (1- (+ bit-offset width))). Can be used with SETF.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para>&#x00A0;</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>ptr</term>
+
+	      <listitem>
+		<para>A MACPTR</para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>bit-offset</term>
+
+		    <listitem>
+		      <para>A fixnum</para>
+		    </listitem>
+		  </varlistentry>
+
+		  <varlistentry>
+		    <term>width</term>
+
+		    <listitem>
+		      <para>A positive fixnum</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
         </sect3>
 =

-        <sect3 id=3D"iint-to-ptr--Function-">
-          <para>%int-to-ptr [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>%int-to-ptr int</variablelist>
-            </indexterm><indexterm>Description
-              <variablelist>Creates and returns a MACPTR whose address mat=
ches int.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> =

-                <term><indexterm>int
-                    <variablelist>An (unsigned-byte 32)</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"iinc-ptr--Function-">
-          <para>%inc-ptr [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>%inc-ptr ptr &amp;optional (delta 1)</variable=
list>
-            </indexterm><indexterm>Description
-              <variablelist>Creates and returns a MACPTR whose address is =
the address ofptr plus delta. The idiom (%inc-ptr ptr 0) is sometimes used =
tocopy a MACPTR, e.g., to create a new MACPTR encapsulating the sameaddress=
 as ptr.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> =

-                <term><indexterm>ptr
-                    <variablelist>A MACPTR</variablelist>
-                  </indexterm><indexterm>delta
-                    <variablelist>A fixnum</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"iptr-to-int--Function-">
-          <para>%ptr-to-int [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>%ptr-to-int ptr</variablelist>
-            </indexterm><indexterm>Description
-              <variablelist>Returns the address encapsulated by ptr, as an=
(unsigned-byte 32).</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> =

-                <term><indexterm>ptr
-                    <variablelist>A MACPTR</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"inull-ptr--Macro-">
-          <para>%null-ptr [Macro]</para>
-          <term><indexterm>Syntax
-              <variablelist>%null-ptr</variablelist>
-            </indexterm><indexterm>Description
-              <variablelist>Equivalent to (%ptr-to-int 0).</variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"inull-ptr-p--Function-">
-          <para>%null-ptr-p [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>%null-ptr-p ptr</variablelist>
-            </indexterm><indexterm>Description
-              <variablelist>Returns T If ptr is a MACPTR encapsulating the=
 address 0,NIL if ptr encapsulates some other address.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> =

-                <term><indexterm>ptr
-                    <variablelist>A MACPTR</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"isetf-macptr--Function-">
-          <para>%setf-macptr [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>%setf-macptr dest-ptr src-ptr</variablelist>
-            </indexterm><indexterm>Description
-              <variablelist>Causes dest-ptr to encapsulate the same addres=
s that src-ptrdoes, then returns dest-ptr.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> =

-                <term><indexterm>dest-ptr
-                    <variablelist>A MACPTR</variablelist>
-                  </indexterm><indexterm>src-ptr
-                    <variablelist>A MACPTR</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"iincf-ptr--Macro-">
-          <para>%incf-ptr [Macro]</para>
-          <term><indexterm>Syntax
-              <variablelist>%incf-ptr ptr &amp;optional (delta 1)</variabl=
elist>
-            </indexterm><indexterm>Description
-              <variablelist>Destructively modifies ptr, by adding delta to=
 the addressit encapsulates. Returns ptr.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> =

-                <term><indexterm>ptr
-                    <variablelist>A MACPTR</variablelist>
-                  </indexterm><indexterm>delta
-                    <variablelist>A fixnum</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"with-macptrs--Macro-">
-          <para>with-macptrs [Macro]</para>
-          <term><indexterm>Syntax
-              <variablelist>with-macptrs (var expr)* &amp;body body</varia=
blelist>
-            </indexterm><indexterm>Description
-              <variablelist>Executes body in an environment in which each =
var is boundto a stack-allocated macptr which encapsulates the foreign addr=
essyielded by the corresponding expr. Returns whatever value(s) bodyreturns=
.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> =

-                <term><indexterm>var
-                    <variablelist>A symbol (variable name)</variablelist>
-                  </indexterm><indexterm>expr
-                    <variablelist>A MACPTR-valued expression</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"istack-block--Macro-">
-          <para>%stack-block [Macro]</para>
-          <term><indexterm>Syntax
-              <variablelist>%stack-block (var expr)* &amp;body body</varia=
blelist>
-            </indexterm><indexterm>Description
-              <variablelist>Executes body in an environment in which each =
var is boundto a stack-allocated macptr which encapsulates the address of a=
stack-allocated region of size expr bytes. Returns whatevervalue(s) body re=
turns.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> =

-                <term><indexterm>var
-                    <variablelist>A symbol (variable name)</variablelist>
-                  </indexterm><indexterm>expr
-                    <variablelist>An expression which should evaluate to a=
 non-negativefixnum</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"make-cstring--Function-">
-          <para>make-cstring [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>make-cstring string</variablelist>
-            </indexterm><indexterm>Description
-              <variablelist>Allocates a block of memory (via malloc) of le=
ngth (1+(length string)). Copies the string to this block and appends atrai=
ling NUL byte; returns a MACPTR to the block.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> =

-                <term><indexterm>string
-                    <variablelist>A lisp string</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"with-cstrs--Macro-">
-          <para>with-cstrs [Macro]</para>
-          <term><indexterm>Syntax
-              <variablelist>with-cstrs (var string)* &amp;body body</varia=
blelist>
-            </indexterm><indexterm>Description
-              <variablelist>Executes body in an environment in which each =
var is boundto a stack-allocated macptr which encapsulates the %address of =
astack-allocated region of into which each string (and a trailingNUL byte) =
has been copied. Returns whatever value(s) body returns.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> =

-                <term><indexterm>var
-                    <variablelist>A symbol (variable name)</variablelist>
-                  </indexterm><indexterm>string
-                    <variablelist>An expression which should evaluate to a=
 lisp string</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"iget-cstring--Function-">
-          <para>%get-cstring [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>%get-cstring ptr</variablelist>
-            </indexterm><indexterm>Description
-              <variablelist>Interprets ptr as a pointer to a (NUL -termina=
ted) C string;returns an equivalent lisp string.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist>
-                <term><indexterm>ptr
-                    <variablelist>A MACPTR</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id=3D"istr-from-ptr--Function-">
-          <para>%str-from-ptr [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>%str-from-ptr ptr length</variablelist>
-            </indexterm><indexterm>Description
-              <variablelist>Returns a lisp string of length <literal>lengt=
h</literal>,whose contents are initialized from the bytes at<literal> ptr.<=
/literal></variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist>
-                <term><indexterm>ptr
-                    <variablelist>AMACPTR</variablelist>
-                  </indexterm><indexterm>length
-                    <variablelist>anon-negative fixnum</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
+	<sect3>
+	  <title>%int-to-ptr [Function]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%int-to-ptr int</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Creates and returns a MACPTR whose address matches int.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para>&#x00A0;</para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>int</term>
+
+		    <listitem>
+		      <para>An (unsigned-byte 32)</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
+
+	<sect3>
+	  <title>%inc-ptr [Function]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%inc-ptr ptr &#38;optional (delta 1)</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Creates and returns a MACPTR whose address is the address of
+		ptr plus delta. The idiom (%inc-ptr ptr 0) is sometimes used to
+		copy a MACPTR, e.g., to create a new MACPTR encapsulating the same
+		address as ptr.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para>&#x00A0;</para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>ptr</term>
+
+		    <listitem>
+		      <para>A MACPTR</para>
+		    </listitem>
+		  </varlistentry>
+
+		  <varlistentry>
+		    <term>delta</term>
+
+		    <listitem>
+		      <para>A fixnum</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
+
+	<sect3>
+	  <title>%ptr-to-int [Function]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%ptr-to-int ptr</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Returns the address encapsulated by ptr, as an
+		(unsigned-byte 32).</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para>&#x00A0;</para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>ptr</term>
+
+		    <listitem>
+		      <para>A MACPTR</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
+
+	<sect3>
+	  <title>%null-ptr [Macro]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%null-ptr</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Equivalent to (%ptr-to-int 0).</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
+
+	<sect3>
+	  <title>%null-ptr-p [Function]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%null-ptr-p ptr</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Returns T If ptr is a MACPTR encapsulating the address 0,
+		NIL if ptr encapsulates some other address.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para>&#x00A0;</para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>ptr</term>
+
+		    <listitem>
+		      <para>A MACPTR</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
+
+	<sect3>
+	  <title>%setf-macptr [Function]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%setf-macptr dest-ptr src-ptr</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Causes dest-ptr to encapsulate the same address that src-ptr
+		does, then returns dest-ptr.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para>&#x00A0;</para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>dest-ptr</term>
+
+		    <listitem>
+		      <para>A MACPTR</para>
+		    </listitem>
+		  </varlistentry>
+
+		  <varlistentry>
+		    <term>src-ptr</term>
+
+		    <listitem>
+		      <para>A MACPTR</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
+
+	<sect3>
+	  <title>%incf-ptr [Macro]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%incf-ptr ptr &#38;optional (delta 1)</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Destructively modifies ptr, by adding delta to the address
+		it encapsulates. Returns ptr.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para>&#x00A0;</para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>ptr</term>
+
+		    <listitem>
+		      <para>A MACPTR</para>
+		    </listitem>
+		  </varlistentry>
+
+		  <varlistentry>
+		    <term>delta</term>
+
+		    <listitem>
+		      <para>A fixnum</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
+
+	<sect3>
+	  <title>with-macptrs [Macro]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>with-macptrs (var expr)* &#38;body body</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Executes body in an environment in which each var is bound
+		to a stack-allocated macptr which encapsulates the foreign address
+		yielded by the corresponding expr. Returns whatever value(s) body
+		returns.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para>&#x00A0;</para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>var</term>
+
+		    <listitem>
+		      <para>A symbol (variable name)</para>
+		    </listitem>
+		  </varlistentry>
+
+		  <varlistentry>
+		    <term>expr</term>
+
+		    <listitem>
+		      <para>A MACPTR-valued expression</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
+
+	<sect3>
+	  <title>%stack-block [Macro]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%stack-block (var expr)* &#38;body body</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Executes body in an environment in which each var is bound
+		to a stack-allocated macptr which encapsulates the address of a
+		stack-allocated region of size expr bytes. Returns whatever
+		value(s) body returns.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para>&#x00A0;</para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>var</term>
+
+		    <listitem>
+		      <para>A symbol (variable name)</para>
+		    </listitem>
+		  </varlistentry>
+
+		  <varlistentry>
+		    <term>expr</term>
+
+		    <listitem>
+		      <para>An expression which should evaluate to a non-negative
+		      fixnum</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
+
+	  <sect3>
+	    <title>make-cstring [Function]</title>
+
+	    <variablelist>
+	      <varlistentry>
+		<term>Syntax</term>
+
+		<listitem>
+		  <para>make-cstring string</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>Description</term>
+
+		<listitem>
+		  <para>Allocates a block of memory (via malloc) of length (1+
+		  (length string)). Copies the string to this block and appends a
+		  trailing NUL byte; returns a MACPTR to the block.</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>Arguments</term>
+
+		<listitem>
+		  <para>&#x00A0;</para>
+
+		  <variablelist>
+		    <varlistentry>
+		      <term>string</term>
+
+		      <listitem>
+			<para>A lisp string</para>
+		      </listitem>
+		    </varlistentry>
+		  </variablelist>
+		</listitem>
+	      </varlistentry>
+	    </variablelist>
+	  </sect3>
+
+	<sect3>
+	  <title>with-cstrs [Macro]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>with-cstrs (var string)* &#38;body body</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Executes body in an environment in which each var is bound
+		to a stack-allocated macptr which encapsulates the %address of a
+		stack-allocated region of into which each string (and a trailing
+		NUL byte) has been copied. Returns whatever value(s) body returns.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para>&#x00A0;</para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>var</term>
+
+		    <listitem>
+		      <para>A symbol (variable name)</para>
+		    </listitem>
+		  </varlistentry>
+
+		  <varlistentry>
+		    <term>string</term>
+
+		    <listitem>
+		      <para>An expression which should evaluate to a lisp string</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
+
+	<sect3>
+	  <title>%get-cstring [Function]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%get-cstring ptr</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Interprets ptr as a pointer to a (NUL -terminated) C string;
+		returns an equivalent lisp string.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para></para>
+
+		<variablelist>
+		  <varlistentry>
+		    <term>ptr</term>
+
+		    <listitem>
+		      <para>A MACPTR</para>
+		    </listitem>
+		  </varlistentry>
+		</variablelist>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
+
+	<sect3>
+	  <title>%str-from-ptr [Function]</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>Syntax</term>
+
+	      <listitem>
+		<para>%str-from-ptr ptr length</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Description</term>
+
+	      <listitem>
+		<para>Returns a lisp string of length <varname>length</varname>,
+		whose contents are initialized from the bytes at<varname> ptr.</varname>
+		</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>Arguments</term>
+
+	      <listitem>
+		<para><variablelist><varlistentry><term>ptr</term><listitem><para>A
+		MACPTR</para></listitem></varlistentry><varlistentry><term>length</term>=
<listitem><para>a
+		non-negative fixnum</para></listitem></varlistentry></variablelist></par=
a>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
       </sect2>
     </sect1>
 =

@@ -5884,11 +8562,15 @@
         obtaining current interface database files.</para>
         <para>Not surprisingly, different platforms use different database=
 files.</para>
         <para>OpenMCL defines reader macros that consult these databases:<=
/para>
-        <listitem mark=3D"bullet">
-          <variablelist>#$foo looks up the value of the constant definitio=
n of FIXTHIS</variablelist>
-          <variablelist>#_foo looks up the foreign function definition for=
 FIXTHIS</variablelist>
+	<itemizedlist>
+          <listitem>
+	    <para>#$foo looks up the value of the constant definition of foo</par=
a>
+	  </listitem>
+	  <listitem>
+	    <para>#_foo looks up the foreign function definition for foo</para>
+	  </listitem>
         =

-        </listitem>
+        </itemizedlist>
         <para>In both cases, the symbol foo is interned in the "OS"
         package. The #$ reader macro has the side-effect of defining
         foo as a constant (as if via DEFCONSTANT); the #_ reader macro
@@ -6026,172 +8708,255 @@
         used instead.</para>
         <para>To create a new interface directory, "foo", and a set of
         database files in that directory:</para>
-        <varlistentry numeration=3D"arabic">
-          <variablelist>Create a subdirectory of "ccl:headers;" named"foo"=
.</variablelist>
-          <variablelist>Create a subdirectory of "ccl:headers;foo;" named"=
C".</variablelist>
-          <variablelist>Create a file in "ccl:headers;foo;C;" named"popula=
te.sh".One way of accomplishing the above steps is:
-            <programlisting>
-? (close (open "ccl:headers;foo;C;populate.sh" :direction :output :
-               if-does-not-exist :create :if-exists :overwrite))
-</programlisting></variablelist>
-          <variablelist>Edit the file created above, using the "populate.s=
h"files in the distribution as guidelines.The file might wind up looking so=
mething like:
-            <programlisting>
-#/bin/sh
-h-to-ffi.sh `foo-config -cflags` /usr/include/foo/foo.h
-</programlisting></variablelist>
-        </varlistentry>
-        <para>Refer to =

-for information about running the
-interface translator and .ffi parser.</para>
-        <para>Assuming that all went well, there should now be .cdb files =
in
-"ccl:headers;foo;". You can then do
-<code>(use-interface-dir :foo)</code> whenever you need to
-access the foreign type information in those database files.</para>
+	<orderedlist continuation=3D"restarts" inheritnum=3D"ignore">
+	  <listitem>
+	    <para>Create a subdirectory of &#34;ccl:headers;&#34; named
+	    &#34;foo&#34;.</para>
+	  </listitem>
+
+	  <listitem>
+	    <para>Create a subdirectory of &#34;ccl:headers;foo;&#34; named
+	    &#34;C&#34;.</para>
+	  </listitem>
+
+	  <listitem>
+	    <para>Create a file in &#34;ccl:headers;foo;C;&#34; named
+	    &#34;populate.sh&#34;.</para>
+
+	    <para>One way of accomplishing the above steps is:</para>
+
+	    <programlisting format=3D"linespecific">? (close (open &#34;ccl:heade=
rs;foo;C;populate.sh&#34; :direction :output :
+               if-does-not-exist :create :if-exists :overwrite))</programl=
isting>
+	  </listitem>
+
+	  <listitem>
+	    <para>Edit the file created above, using the &#34;populate.sh&#34;
+	    files in the distribution as guidelines.</para>
+
+	    <para>The file might wind up looking something like:</para>
+
+	    <programlisting format=3D"linespecific">#/bin/sh
+h-to-ffi.sh `foo-config -cflags` /usr/include/foo/foo.h</programlisting>
+	  </listitem>
+	</orderedlist>
+
+        <para>Refer to <xref linkend=3D"The-Interface-Translator"/> for
+        information about running the interface translator and .ffi
+        parser.</para>
+        <para>Assuming that all went well, there should now be .cdb
+        files in "ccl:headers;foo;". You can then do
+        <programlisting>
+? (use-interface-dir :foo)
+	</programlisting> =

+	whenever you need to
+        access the foreign type information in those database
+        files.</para>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"Using-Shared-Libraries">
-      <para>Using Shared Libraries</para>
-
-      <sect2 id=3D"Overview--13-">
-        <para>Overview
-OpenMCL provides facilities to open and close shared libraries.</para>
-        <para>"Opening" a shared library, which is done with
-, maps the library's
-code and
-data into OpenMCL's address space and makes its exported symbols
-accessible to OpenMCL.</para>
-        <para>"Closing" a shared library, which is done with
-, unmaps the
-library's code and
-data and removes the library's symbols from the global namespace.</para>
-        <para>A small number of shared libraries (including libc, libm, li=
bdl
-under Linux, and the "system" library under Darwin) are opened by
-the lisp kernel and can't be closed.</para>
-        <para>OpenMCL uses data structures of type EXTERNAL-ENTRY-POINT to=
 map a
-foreign function name (string) to that foreign function's
-<emphasis>current<</emphasis> address. (A function's address may
-vary from session to session as different versions of shared libraries may
-load at different addresses; it may vary within a session for similar
-reasons.)</para>
-        <para>An EXTERNAL-ENTRY-POINT whose address is known is said to be
-<emphasis>resolved</emphasis>. When an external entry point is resolved,
-the shared library which defines that entry point is noted; when a shared
-library is closed, the entry points that it defines are made unresolved.
-An EXTERNAL-ENTRY-POINT must be in the resolved state in order to be
-FF-CALLed; calling an unresolved entry point causes a "last
-chance" attempt to resolve it. Attempting to resolve an entrypoint
-that was defined in a closed library will cause an attempt to reopen that
-library.</para>
-        <para>OpenMCL keeps track of all libraries that have been opened i=
n a lisp
-session. When a saved application is first started, an attempt is made to
-reopen all libraries that were open when the image was saved, and an
-attempt is made to resolve all entrypoints that had been referenced when
-the image was saved. Either of these attempts can fail "quietly",
-leaving some entry points in an unresolved state.</para>
-        <para>Linux shared libraries can be referred to either by a string=
 which
-describes their full pathname or by their <emphasis>soname</emphasis>, a
-shorter string that can be defined when the library is created. The
-dynamic linker mechanisms used in Linux make it possible (through a series
-of filesystem links and other means) to refer to a library via several
-names; the library's soname is often the most appropriate identifier.</par=
a>
-        <para>sonames are often less version-specific than other names for
-libraries; a program that refers to a library by the name
-"libc.so.6" is more portable than one which refers to
-"libc-2.1.3.so" or to "libc-2.2.3.so", even though the
-latter two names might each be platform-specific aliases of the first.</pa=
ra>
-        <para>All of the global symbols described below are exported from =
the CCL
-package.</para>
+      <title>Using Shared Libraries</title>
+
+      <sect2 id=3D"Shared-Library-Overview">
+	<title>Overview</title>
+
+        <para>OpenMCL provides facilities to open and close shared
+        libraries.</para>
+        <para>"Opening" a shared library, which is done with <xref
+        linkend=3D"f_open-shared-library"/>, maps the library's code and
+        data into OpenMCL's address space and makes its exported
+        symbols accessible to OpenMCL.</para>
+        <para>"Closing" a shared library, which is done with <xref
+        linkend=3D"f_close-shared-library"/>, unmaps the library's code
+        and and removes the library's symbols from the global
+        namespace.</para>
+        <para>A small number of shared libraries (including libc,
+        libm, libdl under Linux, and the "system" library under
+        Darwin) are opened by the lisp kernel and can't be
+        closed.</para>
+        <para>OpenMCL uses data structures of type
+        EXTERNAL-ENTRY-POINT to map a foreign function name (string)
+        to that foreign function's <emphasis>current</emphasis>
+        address. (A function's address may vary from session to
+        session as different versions of shared libraries may load at
+        different addresses; it may vary within a session for similar
+        reasons.)</para>
+        <para>An EXTERNAL-ENTRY-POINT whose address is known is said
+        to be <emphasis>resolved</emphasis>. When an external entry
+        point is resolved, the shared library which defines that entry
+        point is noted; when a shared library is closed, the entry
+        points that it defines are made unresolved.  An
+        EXTERNAL-ENTRY-POINT must be in the resolved state in order to
+        be FF-CALLed; calling an unresolved entry point causes a "last
+        chance" attempt to resolve it. Attempting to resolve an
+        entrypoint that was defined in a closed library will cause an
+        attempt to reopen that library.</para>
+        <para>OpenMCL keeps track of all libraries that have been
+        opened in a lisp session. When a saved application is first
+        started, an attempt is made to reopen all libraries that were
+        open when the image was saved, and an attempt is made to
+        resolve all entrypoints that had been referenced when the
+        image was saved. Either of these attempts can fail "quietly",
+        leaving some entry points in an unresolved state.</para>
+        <para>Linux shared libraries can be referred to either by a
+        string which describes their full pathname or by their
+        <emphasis>soname</emphasis>, a shorter string that can be
+        defined when the library is created. The dynamic linker
+        mechanisms used in Linux make it possible (through a series of
+        filesystem links and other means) to refer to a library via
+        several names; the library's soname is often the most
+        appropriate identifier.</para>
+        <para>sonames are often less version-specific than other names
+        for libraries; a program that refers to a library by the name
+        "libc.so.6" is more portable than one which refers to
+        "libc-2.1.3.so" or to "libc-2.2.3.so", even though the latter
+        two names might each be platform-specific aliases of the
+        first.</para>
+        <para>All of the global symbols described below are exported
+        from the CCL package.</para>
       </sect2>
 =

       <sect2 id=3D"Limitations-and-known-bugs--1-">
-        <para>Limitations and known bugs</para>
-        <listitem mark=3D"bullet">
-          <variablelist>Don't get me started.</variablelist>
-          <variablelist>The underlying functionality has a poor notion of =
dependency;it's not always possible to open libraries that depend on unopen=
edlibraries, but it's possible to close libraries on which otherlibraries d=
epend.It <emphasis>may</emphasis> be possible to generate moreexplicit depe=
ndency information by parsing the output of the Linux lddand ldconfig progr=
ams.</variablelist>
+        <title>Limitations and known bugs</title>
+	<itemizedlist>
+          <listitem>
+	    <para>Don't get me started.</para>
+	  </listitem>
+          <listitem>
+	    <para>The underlying functionality has a poor notion of
+	    dependency;it's not always possible to open libraries that
+	    depend on unopened libraries, but it's possible to close
+	    libraries on which other libraries depend. It
+	    <emphasis>may</emphasis> be possible to generate
+	    more explicit dependency information by parsing the output
+	    of the Linux ldd and ldconfig programs.</para>
+	  </listitem>
         =

-        </listitem>
+	</itemizedlist>
       </sect2>
 =

       <sect2 id=3D"Darwin-Notes">
-        <para>Darwin Notes
-Darwin shared libraries come in two (basic) flavors:</para>
-        <listitem mark=3D"bullet">
-          <variablelist>"dylibs" (which often have the extension".dylib") =
are primarily intended to be linked against atcompile/link time. They can b=
e loaded dynamically,<emphasis>but can't be unloaded</emphasis>. Accordingl=
y,OPEN-SHARED-LIBRARY can be used to open a .dylib-style library;calling CL=
OSE-SHARED-LIBRARY on the result of such a callproduces a warning, and has =
no other effect.It appears that (due to an OS bug) attempts to open .dylibs=
hared-libraries that are already open can cause memory corruptionunless the=
 full pathname of the .dylib file is specified on thefirst and all subseque=
nt calls.</variablelist>
-          <variablelist>"bundles" are intended to serve as applicationexte=
nsions; they can be opened multiple times (creating multipleinstances of th=
e library!) and closed properly.</variablelist>
-        =

-        </listitem>
-        <para>Thanks to Michael Klingbeil for getting both kinds of Darwin=
 shared
-libraries working in OpenMCL.</para>
+        <title>>Darwin Notes</title>
+	<para>Darwin shared libraries come in two (basic) flavors:</para>
+	<itemizedlist>
+          <listitem>
+	    <para>"dylibs" (which often have the extension".dylib")
+	    are primarily intended to be linked against atcompile/link
+	    time. They can be loaded dynamically,<emphasis>but can't
+	    be unloaded</emphasis>. Accordingly,OPEN-SHARED-LIBRARY
+	    can be used to open a .dylib-style library;calling
+	    CLOSE-SHARED-LIBRARY on the result of such a callproduces
+	    a warning, and has no other effect.It appears that (due to
+	    an OS bug) attempts to open .dylibshared-libraries that
+	    are already open can cause memory corruptionunless the
+	    full pathname of the .dylib file is specified on thefirst
+	    and all subsequent calls.</para>
+	  </listitem>
+          <listitem>
+	    <para>"bundles" are intended to serve as application
+	    extensions; they can be opened multiple times (creating
+	    multiple instances of the library!) and closed
+	    properly.</para>
+          </listitem>
+	</itemizedlist>
+        <para>Thanks to Michael Klingbeil for getting both kinds of
+        Darwin shared libraries working in OpenMCL.</para>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"The-Interface-Translator">
-      <para>The Interface Translator</para>
-
-      <sect2 id=3D"Overview--14-">
-        <para>Overview
-OpenMCL uses an interface translation system based on the FFIGEN
-system, which is described at
-http://www.ccs.neu.edu/home/lth/ffigen/.
-The interface translator makes
-the constant, type, structure, and function definitions in a set of
-C-language header files available to lisp code.</para>
-        <para>The basic idea of the FFIGEN scheme is to use the C compiler=
's
-frontend and parser to translate .h files into semantically equivalent
-.ffi files, which represent the definitions from the headers using a
-syntax based on S-expressions.
-Lisp code can then concentrate on
-the .ffi representation, without having to concern itself with the
-semantics of header file inclusion or the arcana of C parsing.</para>
-        <para>The original FFIGEN system used a modified version of the LC=
C C
-compiler to produce .ffi files. Since many LinuxPPC header files contain
-GCC-specific constructs, OpenMCL's translation system uses a modified
-version of GCC (called, somewhat confusingly, ffigen.)</para>
-        <para>A version of ffigen based on GCC-4.0 was developed during th=
e spring
-and summer of 2005.  Sources (diffs relative to the GCC-4.0 release)
-are available here, and
-binaries are available for
-DarwinPPC
-and for
-LinuxPPC.
-These versions should be insensitive to to the version of GCC (and its
-preprocessor) installed on the system.</para>
-        <para>An older version was developed in 2001-2002; it depended on =
the installed
-version of GCC being 2.95.  It may still be of interest for people unable
-to run the GCC-4.0-based version for whatever reason.</para>
-        <para>A LinuxPPC binary of this older version is available at ftp:=
//clozure.com/pub/ffigen-0.1.tar.gz,
-and LinuxPPC source differences are at ftp://clozure.com/pub/ffigen-src.ta=
r.gz.</para>
-        <para>For Darwin, the binary of the older FFIGEN is available at f=
tp://clozure.com/pub/ffigen-darwin.tar.gz,
-and the source differences are at ftp://clozure.com/pub/ffigen-darwin-src.=
tar.gz.</para>
-        <para>A shell script (distributed with the source and binary packa=
ges)
-called h-to-ffi.sh  reads a specified .h file (and optional
-preprocessor arguments) and writes a (hopefully) equivalent .ffi file to
-standard output, calling the installed C preprocessor and the ffigen
-program with appropriate arguments.</para>
-        <para>For each interface directory (see )
-<emphasis>subdir</emphasis> distributed with OpenMCL, a shell script
-(distributed with OpenMCL as "ccl:headers;<emphasis>subdir</emphasis>;C;po=
pulate.sh"
-("ccl:darwin-headers;<emphasis>subdir</emphasis>;C;populate.sh"
-for Darwin)) calls h-to-ffi.sh on a large number of the header files in
-/usr/include (or some other <emphasis>system header path</emphasis>) and
-creates a parallel directory tree in "ccl:headers;<emphasis>subdir</emphas=
is>;C;<emphasis>system</emphasis>;<emphasis>header</emphasis>;<emphasis>pat=
h</emphasis>;"
-(or "ccl:darwin-headers;<emphasis>subdir</emphasis>;C;<emphasis>system</em=
phasis>;<emphasis>header</emphasis>;<emphasis>path</emphasis>;"),
-populating that directory with .ffi files.</para>
+      <title>The Interface Translator</title>
+
+      <sect2 id=3D"Inteface-translator-overview">
+	<title>Overview</title>
+	<para>OpenMCL uses an interface translation system based on the FFIGEN
+	system, which is described at
+	http://www.ccs.neu.edu/home/lth/ffigen/.
+	The interface translator makes
+	the constant, type, structure, and function definitions in a set of
+	C-language header files available to lisp code.</para>
+        <para>The basic idea of the FFIGEN scheme is to use the C
+        compiler's frontend and parser to translate .h files into
+        semantically equivalent .ffi files, which represent the
+        definitions from the headers using a syntax based on
+        S-expressions.  Lisp code can then concentrate on the .ffi
+        representation, without having to concern itself with the
+        semantics of header file inclusion or the arcana of C
+        parsing.</para>
+        <para>The original FFIGEN system used a modified version of
+        the LCC C compiler to produce .ffi files. Since many LinuxPPC
+        header files contain GCC-specific constructs, OpenMCL's
+        translation system uses a modified version of GCC (called,
+        somewhat confusingly, ffigen.)</para>
+        <para>A version of ffigen based on GCC-4.0 was developed
+        during the spring and summer of 2005.  Sources (diffs relative
+        to the GCC-4.0 release) are available here, and binaries are
+        available for DarwinPPC and for LinuxPPC.  These versions
+        should be insensitive to to the version of GCC (and its
+        preprocessor) installed on the system.</para>
+        <para>An older version was developed in 2001-2002; it depended
+        on the installed version of GCC being 2.95.  It may still be
+        of interest for people unable to run the GCC-4.0-based version
+        for whatever reason.</para>
+        <para>A LinuxPPC binary of this older version is available at
+        ftp://clozure.com/pub/ffigen-0.1.tar.gz, and LinuxPPC source
+        differences are at
+        ftp://clozure.com/pub/ffigen-src.tar.gz.</para>
+        <para>For Darwin, the binary of the older FFIGEN is available
+        at ftp://clozure.com/pub/ffigen-darwin.tar.gz, and the source
+        differences are at
+        ftp://clozure.com/pub/ffigen-darwin-src.tar.gz.</para>
+        <para>A shell script (distributed with the source and binary
+        packages) called h-to-ffi.sh reads a specified .h file (and
+        optional preprocessor arguments) and writes a (hopefully)
+        equivalent .ffi file to standard output, calling the installed
+        C preprocessor and the ffigen program with appropriate
+        arguments.</para>
+        <para>For each interface directory (see FIXTHIS)
+        <emphasis>subdir</emphasis> distributed with OpenMCL, a shell
+        script (distributed with OpenMCL as
+        "ccl:headers;<emphasis>subdir</emphasis>;C;populate.sh"
+        ("ccl:darwin-headers;<emphasis>subdir</emphasis>;C;populate.sh"
+        for Darwin)) calls h-to-ffi.sh on a large number of the header
+        files in /usr/include (or some other <emphasis>system header
+        path</emphasis>) and creates a parallel directory tree in
+        "ccl:headers;<emphasis>subdir</emphasis>;C;<emphasis>system</empha=
sis>;<emphasis>header</emphasis>;<emphasis>path</emphasis>;"
+        (or
+        "ccl:darwin-headers;<emphasis>subdir</emphasis>;C;<emphasis>system=
</emphasis>;<emphasis>header</emphasis>;<emphasis>path</emphasis>;"),
+        populating that directory with .ffi files.</para>
         <para>A lisp function defined in "ccl:library;parse-ffi.lisp"
-reads the .ffi files in a specified interface directory
-<emphasis>subdir</emphasis> and generates new versions of the databases
-(files with the extension .cdb).</para>
-        <para>The CDB databases are used by the #$ and #_ reader macros an=
d are
-used in the expansion of RREF, RLET, and related macros.</para>
+        reads the .ffi files in a specified interface directory
+        <emphasis>subdir</emphasis> and generates new versions of the
+        databases (files with the extension .cdb).</para>
+        <para>The CDB databases are used by the #$ and #_ reader
+        macros and are used in the expansion of RREF, RLET, and
+        related macros.</para>
       </sect2>
 =

       <sect2 id=3D"Details--rebuilding-the-CDB-databases--step-by-step">
-        <para>Details: rebuilding the CDB databases, step by step</para>
-        <varlistentry numeration=3D"arabic">
-          <variablelist>Ensure that the FFIGEN program is installed. See t=
he"README" file in the source or binary archive for specificinstallation in=
structions.This example assumes LinuxPPC; for 32-bit DarwinPPC, substitute"=
ccl:darwin-headers;" for "ccl:headers;".   For 64-bit DarwinPPC,substitute =
"ccl:darwin-headers64;".</variablelist>
-          <variablelist>Edit the "ccl:headers;<emphasis>subdir</emphasis>;=
C;populate.sh"shell script. When you're confident that the files andpreproc=
essor options match your environment, cd to the"ccl:headers;<emphasis>subdi=
r</emphasis>;C;" directory andinvoke ./populate.sh. Repeat this step until =
you're able tocleanly translate all files refrenced in the shell script.</v=
ariablelist>
-          <variablelist>Run OpenMCL:
+        <title>Details: rebuilding the CDB databases, step by step</title>
+	<orderedlist>
+	  <listitem>
+	    <para>Ensure that the FFIGEN program is installed. See
+	    the"README" file in the source or binary archive for
+	    specificinstallation instructions.This example assumes
+	    LinuxPPC; for 32-bit DarwinPPC,
+	    substitute"ccl:darwin-headers;" for "ccl:headers;".  For
+	    64-bit DarwinPPC,substitute
+	    "ccl:darwin-headers64;".</para>
+	  </listitem>
+          <listitem>
+	    <para>Edit the
+	    "ccl:headers;<emphasis>subdir</emphasis>;C;populate.sh"shell
+	    script. When you're confident that the files
+	    andpreprocessor options match your environment, cd to
+	    the"ccl:headers;<emphasis>subdir</emphasis>;C;" directory
+	    andinvoke ./populate.sh. Repeat this step until you're
+	    able tocleanly translate all files refrenced in the shell
+	    script.</para>
+	  </listitem>
+	  <listitem>
+	    <para>Run OpenMCL:
             <programlisting>
 ? (require "PARSE-FFI")
 PARSE-FFI
@@ -6200,55 +8965,55 @@
 ;;; lots of output ... after a while, shiny new .cdb files should
 ;;; appear in "ccl:headers;subdir;"
 ;;; (or "ccl:darwin-headers;subdir;" under Darwin)
-</programlisting></variablelist>
-        </varlistentry>
-        <para>PARSE-STANDARD-FFI-FILES accepts a :PREPEND-UNDERSCORES keyw=
ord
-argument. Darwin (and some other platforms) use a convention wherein the
-symbols associated with C-visible external function and variables have
-underscore characters prepended to their names. When this argument is
-true, PARSE-STANDARD-FFI-FILES will prepend underscores to all foreign
-function names written to the database, so that (#_foo ...) expands into
-an EXTERNAL-CALL to "_foo".</para>
+</programlisting></para>
+	  </listitem>
+	</orderedlist>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"Case-sensitivity-of-foreign-names-in-OpenMCL">
-      <para>Case-sensitivity of foreign names in OpenMCL</para>
-
-      <sect2 id=3D"Overview--15-">
-        <para>Overview
-As of release 0.11, OpenMCL addresses the fact that foreign type,
-constant, record, field, and function nams are case-sensitive and provides
-mechanisms to refer to these names via lisp symbols.</para>
-        <para>Previous versions of OpenMCL have tried to ignore that fact,=
 under
-the belief that case conflicts were rare and that many users (and
-implementors) would prefer not to deal with case-related issues. The fact
-that some information in the interface databases was incomplete or
-inaccessable because of this policy made it clearer that the policy was
-untenable. I can't claim that the approach described here is
-aesthetically pleasing, but I can honestly say that it's less
-unpleasant than other approaches that I'd thought of. I'd be
-interested to hear alternate proposals.</para>
-        <para>The issues described here have to do with how lisp symbols a=
re used
-to denote foreign functions, constants, types, records, and fields. It
-doesn't affect how other lisp objects are sometimes used to denote
-foreign objects. For instance, the first argument to the EXTERNAL-CALL
-macros is now and has always been a case-sensitive string.</para>
+      <title>Case-sensitivity of foreign names in OpenMCL</title>
+
+      <sect2 id=3D"Case-sensitivity-overview">
+	<title>Overview</title>
+	<para>As of release 0.11, OpenMCL addresses the fact that
+	foreign type, constant, record, field, and function nams are
+	case-sensitive and provides mechanisms to refer to these names
+	via lisp symbols.</para>
+        <para>Previous versions of OpenMCL have tried to ignore that
+        fact, under the belief that case conflicts were rare and that
+        many users (and implementors) would prefer not to deal with
+        case-related issues. The fact that some information in the
+        interface databases was incomplete or inaccessable because of
+        this policy made it clearer that the policy was untenable. I
+        can't claim that the approach described here is aesthetically
+        pleasing, but I can honestly say that it's less unpleasant
+        than other approaches that I'd thought of. I'd be interested
+        to hear alternate proposals.</para>
+        <para>The issues described here have to do with how lisp
+        symbols are used to denote foreign functions, constants,
+        types, records, and fields. It doesn't affect how other lisp
+        objects are sometimes used to denote foreign objects. For
+        instance, the first argument to the EXTERNAL-CALL macros is
+        now and has always been a case-sensitive string.</para>
       </sect2>
 =

       <sect2 id=3D"Foreign-constant-and-function-names">
-        <para>Foreign constant and function names
-The primary way of referring to foreign constant and function names
-in OpenMCL is via the #$ and #_ reader macros. These reader macro
-functions each read a symbol into the "OS" package, look up its
-constant or function definition in the interface database, and assign the
-value of the constant to the symbol or install a macroexpansion function
-on the symbol.</para>
-        <para>In order to observe case-sensitivity, the reader-macros now =
read the
-symbol with (READTABLE-CASE :PRESERVE) in effect.</para>
-        <para>This means that it's necessary to type the foreign constant =
or
-function name in correct case, but it isn't necessary to use any
-special escaping constructs when writing the variable name. For instance:<=
/para>
+	<title>Foreign constant and function names</title>
+        <para>The primary way of referring to foreign constant and
+        function names in OpenMCL is via the #$ and #_ reader
+        macros. These reader macro functions each read a symbol into
+        the "OS" package, look up its constant or function definition
+        in the interface database, and assign the value of the
+        constant to the symbol or install a macroexpansion function on
+        the symbol.</para>
+        <para>In order to observe case-sensitivity, the reader-macros
+        now read the symbol with (READTABLE-CASE :PRESERVE) in
+        effect.</para>
+        <para>This means that it's necessary to type the foreign
+        constant or function name in correct case, but it isn't
+        necessary to use any special escaping constructs when writing
+        the variable name. For instance:</para>
         <programlisting>
 (#_read fd buf n) ; refers to foreign symbol "read"
 (#_READ fd buf n) ; refers to foreign symbol "READ", which may
@@ -6259,79 +9024,99 @@
       </sect2>
 =

       <sect2 id=3D"Foreign-type--record--and-field-names">
-        <para>Foreign type, record, and field names
-Constructs like RLET expect a foreign type or record name to be
-denoted by a symbol (typically a keyword); RREF (and PREF) expect an
-"accessor" form, typically a keyword formed by concatenating a
-foreign type or record name with a sequence of one or more foreign field
-names, separated by dots. These names are interned by the reader as other
-lisp symbols are, with an arbitrary value of READTABLE-CASE in effect
-(typically :UPCASE.) It seems like it would be very tedious to force users
-to manually escape (via vertical bar or backslash syntax) all lowercase
-characters in symbols used to specify foreign type, record, and field
-names (especially given that many traditional POSIX structure, type, and
-field names are entirely lowercase.)</para>
-        <para>The approach taken by OpenMCL is to allow the symbols (keywo=
rds)
-used to denote foreign type, record, and field names to contain angle
-brackets (< and >). Such symbols are translated to foreign names
-via the following set of conventions:</para>
-        <listitem mark=3D"bullet">
-          <variablelist>All instances of < and > in the symbol's pname are=
balanced and don't nest.</variablelist>
-          <variablelist>Any alphabetic characters in the symbol's pname th=
ataren't enclosed in angle brackets are treated as lower-case,regardless of=
 the value of READTABLE-CASE and regardless of the casein which they were w=
ritten.</variablelist>
-          <variablelist>Alphabetic characters that appear within angle bra=
ckets aremapped to upper-case, again regardless of how they were written or=
interned.</variablelist>
-        =

-        </listitem>
-        <para>There may be many ways of "escaping" (with angle brackets)
-sequences of upper-case and non-lower-case characters in a symbol used to
-denote a foreign name. When translating in the other direction, OpenMCL
-always escapes the longest sequence that starts with an upper-case
-character and doesn't contain a lower-case character.</para>
-        <para>It's often preferable to use this canonical form of a foreign
-type name.</para>
-        <para>The accessor forms used by PREF/RREF should be viewed as a s=
eries of
-foreign type/record and field names; upper-case sequences in the component
-names should be escaped with angle brackets, but those sequences
-shouldn't span components. (More simply, the separating dots
-shouldn't be enclosed, even if both surrounding characters need to
-be.)</para>
-        <para>Older POSIX code tends to use lower-case exclusively for typ=
e,
-record, and field names; there are only a few cases in the OpenMCL sources
-where mixed-case names need to be escaped.</para>
+	<title>Foreign type, record, and field names</title>
+	<para>Constructs like RLET expect a foreign type or record
+	name to be denoted by a symbol (typically a keyword); RREF
+	(and PREF) expect an "accessor" form, typically a keyword
+	formed by concatenating a foreign type or record name with a
+	sequence of one or more foreign field names, separated by
+	dots. These names are interned by the reader as other lisp
+	symbols are, with an arbitrary value of READTABLE-CASE in
+	effect (typically :UPCASE.) It seems like it would be very
+	tedious to force users to manually escape (via vertical bar or
+	backslash syntax) all lowercase characters in symbols used to
+	specify foreign type, record, and field names (especially
+	given that many traditional POSIX structure, type, and field
+	names are entirely lowercase.)</para>
+        <para>The approach taken by OpenMCL is to allow the symbols
+        (keywords) used to denote foreign type, record, and field
+        names to contain angle brackets (<literal>&lt;</literal> and
+        <literal>&gt;</literal>). Such symbols are translated to
+	foreign names via the following set of conventions:</para>
+	<itemizedlist>
+          <listitem>
+	    <para>All instances of &lt; and &gt; in the symbol's pname
+	    are balanced and don't nest.</para>
+	  </listitem>
+          <listitem>
+	    <para>Any alphabetic characters in the symbol's pname
+	    thataren't enclosed in angle brackets are treated as
+	    lower-case,regardless of the value of READTABLE-CASE and
+	    regardless of the case in which they were written.</para>
+	  </listitem>
+          <listitem>
+	    <para>Alphabetic characters that appear within angle
+	    brackets aremapped to upper-case, again regardless of how
+	    they were written orinterned.</para>
+	  </listitem>
+        </itemizedlist>
+	<para>There may be many ways of "escaping" (with angle
+	brackets) sequences of upper-case and non-lower-case
+	characters in a symbol used to denote a foreign name. When
+	translating in the other direction, OpenMCL always escapes the
+	longest sequence that starts with an upper-case character and
+	doesn't contain a lower-case character.</para>
+        <para>It's often preferable to use this canonical form of a
+        foreign type name.</para>
+        <para>The accessor forms used by PREF/RREF should be viewed as
+        a series of foreign type/record and field names; upper-case
+        sequences in the component names should be escaped with angle
+        brackets, but those sequences shouldn't span components. (More
+        simply, the separating dots shouldn't be enclosed, even if
+        both surrounding characters need to be.)</para>
+        <para>Older POSIX code tends to use lower-case exclusively for
+        type, record, and field names; there are only a few cases in
+        the OpenMCL sources where mixed-case names need to be
+        escaped.</para>
+	=

       </sect2>
 =

       <sect2 id=3D"Examples--1-">
-        <para>Examples</para>
+        <title>Examples</title>
         <programlisting>
 ;;; Allocate a record of type "window".
 (rlet ((w :window)) ...)
 ;;; Allocate a record of type "Window", which is probably a
 ;;;  different type
-(rlet ((w :<w>indow)) ...)
+(rlet ((w :&lt;w&gt;indow)) ...)
 ;;; This is equivalent to the last example
-(rlet ((w :<w>INDOW)))
+(rlet ((w :&lt;w&gt;INDOW)))
 </programlisting>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"Tutorial--Using-Basic-Calls-and-Types">
-      <para>Tutorial: Using Basic Calls and Types
-This tutorial is meant to cover the basics of OpenMCL for calling
-external C functions and passing data back and forth.  These basics
-will provide the foundation for more advanced techniques which will
-allow access to the various external libraries and toolkits.</para>
-      <para>The first step is to start with a simple C dynamic library in =
order to
-actually observe what is actually passing between OpenMCL and C.  So,
-some C code is in order:</para>
-      <para>Create the file typetest.c, and put the following code into it=
:</para>
+      <title>Tutorial: Using Basic Calls and Types</title>
+      <para>This tutorial is meant to cover the basics of OpenMCL for
+      calling external C functions and passing data back and forth.
+      These basics will provide the foundation for more advanced
+      techniques which will allow access to the various external
+      libraries and toolkits.</para>
+      <para>The first step is to start with a simple C dynamic library
+      in order to actually observe what is actually passing between
+      OpenMCL and C.  So, some C code is in order:</para>
+      <para>Create the file typetest.c, and put the following code
+      into it:</para>
       <programlisting>
 =

-#include <stdio.h>
+#include &lt;stdio.&gt;
 =

 void
 void_void_test(void)
 {
     printf("Entered %s:\n", __FUNCTION__);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
 }
 =

 signed char
@@ -6340,6 +9125,7 @@
     printf("Entered %s:\n", __FUNCTION__);
     printf("Data In: %d\n", (signed int)data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
 =

@@ -6349,128 +9135,125 @@
     printf("Entered %s:\n", __FUNCTION__);
     printf("Data In: %d\n", (signed int)data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
-</programlisting>
-      <para>This defines three functions.  If you're familiar with C, noti=
ce
-that there's no <literal>main()</literal>, because we're just
-building a library, not an executable.</para>
-      <para>The function <literal>void_void_test()</literal> doesn't take
-any parameters, and doesn't return anything, but it prints two
-lines to let us know it was called.
-<literal>sc_sc_test()</literal> takes a signed char as a
-parameter, prints it, and returns it.
-<literal>uc_uc_test()</literal> does the same thing, but with
-an unsigned char.  Their purpose is just to prove to us
-that we really can call C functions, pass them values, and get
-values back from them.</para>
-      <para><inlinemediaobject name=3D"arb36"></inlinemediaobject></para>
-      <para>This code is compiled into a dynamic library on OS X 10.3.4 wi=
th the
-command:</para>
+      </programlisting>
+      <para>This defines three functions.  If you're familiar with C,
+      notice that there's no <literal>main()</literal>, because we're
+      just building a library, not an executable.</para>
+      <para>The function <literal>void_void_test()</literal> doesn't
+      take any parameters, and doesn't return anything, but it prints
+      two lines to let us know it was called.
+      <literal>sc_sc_test()</literal> takes a signed char as a
+      parameter, prints it, and returns it.
+      <literal>uc_uc_test()</literal> does the same thing, but with an
+      unsigned char.  Their purpose is just to prove to us that we
+      really can call C functions, pass them values, and get values
+      back from them.</para>
+      <para>This code is compiled into a dynamic library on OS X
+      10.3.4 with the command:</para>
       <programlisting>
 =

 gcc -dynamiclib -Wall -o libtypetest.dylib typetest.c \
     -install_name ./libtypetest.dylib
+      </programlisting>
+      <tip><para>Users of 64-bit platforms may need to pass options such
+      as "-m64" to gcc, may need to give the output library a different
+      extension (such as ".so"), and may need to user slightly different
+      values for other options in order to create an equivalent test
+      library.</para></tip>
+
+      <para>The -dynamiclib tells gcc that we will be compiling this
+      into a dynamic library and not an executable binary program.
+      The output filename is "libtypetest.dylib".  Notice that we
+      chose a name which follows the normal OS X convention, being in
+      the form "libXXXXX.dylib", so that other programs can link to
+      the library.  OpenMCL doesn't need it to be this way, but it is
+      a good idea to adhere to existing conventions.</para>
+      <para>The -install_name flag is primarily used when building OS
+      X "bundles".  In this case, we are not using it, so we put a
+      placeholder into it, "./libtypetest.dylib".  If we wanted to use
+      typetest in a bundle, the -install_name argument would be a
+      relative path from some "current" directory.</para>
+      <para>After creating this library, the first step is to tell
+      OpenMCL to open the dynamic library.  This is done by calling
+      .</para>
+      <programlisting>
+
+Welcome to OpenMCL Version (Beta: Darwin) 0.14.2-040506!
+
+? (open-shared-library "/Users/andewl/openmcl/libtypetest.dylib")
+#&lt;SHLIB /Users/andewl/openmcl/libtypetest.dylib #x638EF3E&gt;
 </programlisting>
-      <para>The -dynamiclib tells gcc that we will be compiling this into a
-dynamic library and not an executable binary program.  The output
-filename is "libtypetest.dylib".  Notice that we chose a name which
-follows the normal OS X convention, being in the form
-"libXXXXX.dylib", so that other programs can link to the library.
-OpenMCL doesn't need it to be this way, but it is a good idea to
-adhere to existing conventions.</para>
-      <para>The -install_name flag is primarily used when
-building OS X "bundles".  In this case, we are not using it, so we
-put a placeholder into it, "./libtypetest.dylib".  If we wanted
-to use typetest in a bundle, the -install_name argument would
-be a relative path from some "current" directory.</para>
-      <para>After creating this library, the first step is to tell OpenMCL=
 to open
-the dynamic library.  This is done by calling
-.</para>
-      <programlisting>
-
-Welcome to OpenMCL Version (Beta: Darwin) 0.14.2-040506!
-
-? (open-shared-library "/Users/andewl/openmcl/libtypetest.dylib")
-#<SHLIB /Users/andewl/openmcl/libtypetest.dylib #x638EF3E>
-</programlisting>
-      <para>You should use an absolute path here; using a relative one, su=
ch
-as just "libtypetest.dylib", would appear to work, but there are
-subtle problems which occur after reloading it.  See the Darwin
-notes on
- for details.  It would be
-a bad idea anyway, because software should never rely on its
-starting directory being anything in particular.</para>
+      <para>You should use an absolute path here; using a relative
+      one, such as just "libtypetest.dylib", would appear to work, but
+      there are subtle problems which occur after reloading it.  See
+      the Darwin notes on for details.  It would be a bad idea anyway,
+      because software should never rely on its starting directory
+      being anything in particular.</para>
       <para>This command returns a reference to the opened shared library,=
 and
 OpenMCL also adds one to the global variable
 <literal>ccl::*shared-libraries*</literal>:</para>
       <programlisting>
 =

 ? ccl::*shared-libraries*
-(#<SHLIB /Users/andewl/openmcl/libtypetest.dylib #x638EF3E>
- #<SHLIB /usr/lib/libSystem.B.dylib #x606179E>)
-</programlisting>
-      <para>Before we call anything, let's check that the individual funct=
ions can
-actually be found by the system.  We don't have to do this, but
-it helps to know how to find out whether this is the problem,
-when something goes wrong.
-We use :</para>
+(#&lt;SHLIB /Users/andewl/openmcl/libtypetest.dylib #x638EF3E>
+ #&lt;SHLIB /usr/lib/libSystem.B.dylib #x606179E>)
+      </programlisting>
+      <para>Before we call anything, let's check that the individual
+      functions can actually be found by the system.  We don't have to
+      do this, but it helps to know how to find out whether this is
+      the problem, when something goes wrong.  We use <xref
+      linkend=3D"m_external-call"/>:</para>
       <programlisting>
 =

 ? (external "_void_void_test")
-#<EXTERNAL-ENTRY-POINT "_void_void_test" (#x000CFDF8) /Users/andewl/openmc=
l/libtypetest.dylib #x638EDF6>
+#&lt;EXTERNAL-ENTRY-POINT "_void_void_test" (#x000CFDF8) /Users/andewl/ope=
nmcl/libtypetest.dylib #x638EDF6>
 =

 ? (external "_sc_sc_test")
-#<EXTERNAL-ENTRY-POINT "_sc_sc_test" (#x000CFE50) /Users/andewl/openmcl/li=
btypetest.dylib #x638EB3E>
+#&lt;EXTERNAL-ENTRY-POINT "_sc_sc_test" (#x000CFE50) /Users/andewl/openmcl=
/libtypetest.dylib #x638EB3E>
 =

 ? (external "_uc_uc_test")
-#<EXTERNAL-ENTRY-POINT "_uc_uc_test" (#x000CFED4) /Users/andewl/openmcl/li=
btypetest.dylib #x638E626>
-</programlisting>
-      <para>Notice that the actual function names have
-been "mangled" by the C linker.  The first function was named
-"void_void_test" in typetest.c, but in
-libtypetest.dylib, it has an underscore (a "_" symbol) before
-it: "_void_void_test".  So, this is the name which you have to use.
-The mangling - the way the name is changed - may be different for
-other operating systems or other versions, so you need to "just know"
-how it's done...</para>
-      <para>Also, pay particular attention to the fact
-that a hexadecimal value appears in the EXTERNAL-ENTRY-POINT.
-(#x000CFDF8, for example - but what it is doesn't matter.)
-These hex numbers mean that the
-function can be dereferenced.  Functions which aren't found will
-not have a hex number.  For example:</para>
+#&lt;EXTERNAL-ENTRY-POINT "_uc_uc_test" (#x000CFED4) /Users/andewl/openmcl=
/libtypetest.dylib #x638E626>
+      </programlisting>
+      <para>Notice that the actual function names have been "mangled"
+      by the C linker.  The first function was named "void_void_test"
+      in typetest.c, but in libtypetest.dylib, it has an underscore (a
+      "_" symbol) before it: "_void_void_test".  So, this is the name
+      which you have to use.  The mangling - the way the name is
+      changed - may be different for other operating systems or other
+      versions, so you need to "just know" how it's done...</para>
+      <para>Also, pay particular attention to the fact that a
+      hexadecimal value appears in the EXTERNAL-ENTRY-POINT.
+      (#x000CFDF8, for example - but what it is doesn't matter.)
+      These hex numbers mean that the function can be dereferenced.
+      Functions which aren't found will not have a hex number.  For
+      example:</para>
       <programlisting>
 =

 ? (external "functiondoesnotexist")
-#<EXTERNAL-ENTRY-POINT "functiondoesnotexist" {unresolved}  #x638E3F6>
+#&lt;EXTERNAL-ENTRY-POINT "functiondoesnotexist" {unresolved}  #x638E3F6>
 </programlisting>
       <para>The "unresolved" tells us that OpenMCL wasn't able to find this
-function, which means you would get an error, "Can't resolve foreign
-symbol," if you tried to call it.</para>
-      <para>These
-external function references also are stored in a hash table which is
-accessible through a global variable, <literal>ccl::*eeps*</literal>.</par=
a>
-      <para>At this point, we are ready to try our first external function
-call:</para>
+      function, which means you would get an error, "Can't resolve foreign
+      symbol," if you tried to call it.</para>
+      <para>These external function references also are stored in a
+      hash table which is accessible through a global variable,
+      <literal>ccl::*eeps*</literal>.</para>
+      <para>At this point, we are ready to try our first external
+      function call:</para>
       <programlisting>
 =

 ? (external-call "_void_void_test" :void)
 Entered void_void_test:
 Exited  void_void_test:
 NIL
-</programlisting>
-      <para>We used , which is
-is the normal mechanism for
-accessing externally linked code.  The "_void_void_test"
-is the mangled name of the external function.
-The :void
-refers to the return type of the function.</para>
-      <para>If you're using ILISP to run OpenMCL inside of Emacs, you won't
-see the "Entered" and "Exited" lines until you quit (as of
-July 2004).  It's not
-clear why this is, but it's a pity.  If you want to see them, run
-OpenMCL from Terminal.app or in some other way.</para>
+      </programlisting>
+      <para>We used , which is is the normal mechanism for accessing
+      externally linked code.  The "_void_void_test" is the mangled
+      name of the external function.  The :void refers to the return
+      type of the function.</para>
       <para>The next step is to try passing a value to C, and getting one
 back:</para>
       <programlisting>
@@ -6481,13 +9264,12 @@
 Exited  sc_sc_test:
 -128
 </programlisting>
-      <para>The first :signed-byte gives the type of the first argument,
-and then -128 gives the value to pass for it.  The second
-:signed-byte
-gives the return type.  The return type is always given by the
-last argument to .</para>
+      <para>The first :signed-byte gives the type of the first
+      argument, and then -128 gives the value to pass for it.  The
+      second :signed-byte gives the return type.  The return type is
+      always given by the last argument to .</para>
       <para>Everything looks good.  Now, let's try a number outside
-the range which fits in one byte:</para>
+      the range which fits in one byte:</para>
       <programlisting>
 =

 ? (external-call "_sc_sc_test" :signed-byte -567 :signed-byte)
@@ -6496,8 +9278,8 @@
 Exited  sc_sc_test:
 -55
 </programlisting>
-      <para>Hmmmm.  A little odd.  Let's look at the unsigned stuff
-to see how it reacts:</para>
+      <para>Hmmmm.  A little odd.  Let's look at the unsigned stuff to
+      see how it reacts:</para>
       <programlisting>
 =

 ? (external-call "_uc_uc_test" :unsigned-byte 255 :unsigned-byte)
@@ -6520,21 +9302,22 @@
 Data In: 201
 Exited  uc_uc_test:
 201
-</programlisting>
+      </programlisting>
       <para>Since a signed byte can only hold values from -128 through 127=
, and
-an unsigned one can only hold values from 0 through 255, any number
-outside that range gets "clipped": only the low eight bits of it
-are used.</para>
+      an unsigned one can only hold values from 0 through 255, any number
+      outside that range gets "clipped": only the low eight bits of it
+      are used.</para>
       <para>What is important to remember is that <emphasis>external
-function calls have
-very few safety checks.</emphasis>
-Data outside the valid range for its type will silently do
-very strange things; pointers outside the valid range can very well
-crash the system.</para>
-      <para>That's it for our first example library.  If you're still foll=
owing
-along, let's add some more C code to look at the rest of the
-primitive types.  Then we'll need to recompile the dynamic library,
-load it again, and then we can see what happens.</para>
+      function calls have
+      very few safety checks.</emphasis>
+      Data outside the valid range for its type will silently do
+      very strange things; pointers outside the valid range can very well
+      crash the system.</para>
+      <para>That's it for our first example library.  If you're still
+      following along, let's add some more C code to look at the rest
+      of the primitive types.  Then we'll need to recompile the
+      dynamic library, load it again, and then we can see what
+      happens.</para>
       <para>Add the following code to typetest.c:</para>
       <programlisting>
 =

@@ -6544,6 +9327,7 @@
     printf("Entered %s:\n", __FUNCTION__);
     printf("Data In: %d\n", data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
 =

@@ -6553,6 +9337,7 @@
     printf("Entered %s:\n", __FUNCTION__);
     printf("Data In: %ld\n", data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
 =

@@ -6562,6 +9347,7 @@
     printf("Entered %s:\n", __FUNCTION__);
     printf("Data In: %lld\n", data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
 =

@@ -6571,6 +9357,7 @@
     printf("Entered %s:\n", __FUNCTION__);
     printf("Data In: %e\n", data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
 =

@@ -6580,6 +9367,7 @@
     printf("Entered %s:\n", __FUNCTION__);
     printf("Data In: %e\n", data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
 </programlisting>
@@ -6589,15 +9377,16 @@
 gcc -dynamiclib -Wall -o libtypetest.dylib typetest.c \
     -install_name ./libtypetest.dylib
 </programlisting>
-      <para>Now, restart OpenMCL.  This step is required because OpenMCL c=
annot
-close and reload a dynamic library on OS X.</para>
+      <para>Now, restart OpenMCL.  This step is required because
+      OpenMCL cannot close and reload a dynamic library on OS
+      X.</para>
       <para>Have you restarted?  Okay, try out the new code:</para>
       <programlisting>
 =

 Welcome to OpenMCL Version (Beta: Darwin) 0.14.2-040506!
 =

 ? (open-shared-library "/Users/andewl/openmcl/libtypetest.dylib")
-#<SHLIB /Users/andewl/openmcl/libtypetest.dylib #x638EF3E>
+#&lt;SHLIB /Users/andewl/openmcl/libtypetest.dylib #x638EF3E>
 =

 ? (external-call "_si_si_test" :signed-fullword -178965 :signed-fullword)
 Entered si_si_test:
@@ -6605,7 +9394,7 @@
 Exited  si_si_test:
 -178965
 =

-? ;; long is the same size as int
+? ;; long is the same size as int on 32-bit machines.
 (external-call "_sl_sl_test" :signed-fullword -178965 :signed-fullword)
 Entered sl_sl_test:
 Data In: -178965
@@ -6619,11 +9408,12 @@
 Exited  sll_sll_test:
 -973891578912
 </programlisting>
-      <para>Okay, everything seems to be acting as expected.  However, jus=
t to
-remind you that most of this stuff has no safety net, here's
-what happens if somebody mistakes <literal>sl_sl_test()</literal>
-for <literal>sll_sll_test()</literal>, thinking that a long is
-actually a doubleword:</para>
+      <para>Okay, everything seems to be acting as expected.  However,
+      just to remind you that most of this stuff has no safety net,
+      here's what happens if somebody mistakes
+      <literal>sl_sl_test()</literal> for
+      <literal>sll_sll_test()</literal>, thinking that a long is
+      actually a doubleword:</para>
       <programlisting>
 =

 ? (external-call "_sl_sl_test"
@@ -6632,17 +9422,19 @@
 Data In: -227
 Exited  sl_sl_test:
 -974957576192
-</programlisting>
-      <para>Ouch.  The C function changes the value with no warning that s=
omething
-is wrong.  Even worse, it manages to pass the original value back to
-OpenMCL, which hides the fact that something is wrong.</para>
-      <para>Finally, let's take a look at doing this with floating-point n=
umbers.</para>
+      </programlisting>
+      <para>Ouch.  The C function changes the value with no warning
+      that something is wrong.  Even worse, it manages to pass the
+      original value back to OpenMCL, which hides the fact that
+      something is wrong.</para>
+      <para>Finally, let's take a look at doing this with
+      floating-point numbers.</para>
       <programlisting>
 =

 Welcome to OpenMCL Version (Beta: Darwin) 0.14.2-040506!
 =

 ? (open-shared-library "/Users/andewl/openmcl/libtypetest.dylib")
-#<SHLIB /Users/andewl/openmcl/libtypetest.dylib #x638EF3E>
+#&lt;SHLIB /Users/andewl/openmcl/libtypetest.dylib #x638EF3E>
 =

 ? (external-call "_f_f_test" :single-float -1.256791e+11 :single-float)
 Entered f_f_test:
@@ -6655,7 +9447,7 @@
 Data In: -1.256791e+290
 Exited  d_d_test:
 -1.256791D+290
-</programlisting>
+      </programlisting>
       <para>Notice that the number ends with "...e+11" for the single-floa=
t,
 and "...d+290" for the
 double-float.  Lisp has both of these float types itself, and the
@@ -6669,90 +9461,89 @@
 to pass more complex data structures around.</para>
 =

       <sect2 id=3D"Acknowledgement">
-        <para>Acknowledgement
-This chapter was generously contributed by
-Andrew P. Lentvorski Jr.</para>
+        <title>Acknowledgement</title>
+	<para>This chapter was generously contributed by Andrew
+	P. Lentvorski Jr.</para>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"Tutorial--Allocating-Foreign-Data-on-the-Lisp-Heap">
-      <para>Tutorial: Allocating Foreign Data on the Lisp Heap
-Not every foreign function is so marvelously easy to use as the
-ones we saw in the last section.  Some of them require you to
-allocate a C struct, fill it in with your own information, and
-pass it a pointer to the struct.  Some of them require you to
-allocate an empty struct so they can fill it in, and then you can
-read the information out of it.</para>
-      <para>Also, some of them have their own structs and return a pointer=
 to
-that same struct every time you call them, but those are easier to
-deal with,
-so they won't
-be covered in this section.</para>
-      <para>You might know that Lisp (and, indeed, most programming langua=
ges)
-has two separate regions of memory.  There's the stack, which is
-where variable bindings are kept.  Memory on the stack is allocated
-every time any function is called, and deallocated when it returns,
-so it's useful for anything that doesn't need to last longer than
-one function call, when there's only one thread.  If that's all
-you need, you can do it with
-.</para>
-      <para>Then, there's the heap, which holds everything else, and is our
-subject here.
-There are two advantages and one big disadvantage to putting things on
-the heap rather than the stack.  First, data allocated on the heap can
-be passed outside of the scope in which it was created.  This is
-useful for data which may need to be passed between multiple C calls
-or multiple threads. Also, some data may be too large to copy multiple
-times or may be too large to allocate on the stack.</para>
-      <para>The second advantage is security.  If incoming data is being p=
laced
-directly onto the stack, the input data can cause stack overflows and
-underflows.  This is not something which Lisp users generally worry
-about since garbage collection generally handles memory management.
-However, "stack smashing" is one of the classic exploits in C which
-malicious hackers can use to gain control of a machine.  Not checking
-external
-data is always a bad idea; however, allocating it into the heap at
-least offers more protection than direct stack allocation.</para>
-      <para>The big disadvantage to allocating data on the heap is that it=
 must be
-explicitly deallocated - you need to "free" it when you're done with
-it.  Ordinarily, in Lisp, you wouldn't allocate memory yourself, and
-the garbage collector would know about it, so you wouldn't have to
-think about it again.  When you're doing it manually, it's very
-different.
-Memory management becomes a manual process, just like in C and
-C++.</para>
-      <para>What that means is that, if you allocate something and then lo=
se
-track of the pointer to it,
-there's no way to ever free that
-memory.  That's what's called a memory leak, and if your program
-leaks enough memory it will eventually use up all of it!  So, you
-need to be careful to not lose your pointers.</para>
+      <title>Tutorial: Allocating Foreign Data on the Lisp Heap </title>
+      <para>Not every foreign function is so marvelously easy to use
+      as the ones we saw in the last section.  Some of them require
+      you to allocate a C struct, fill it in with your own
+      information, and pass it a pointer to the struct.  Some of them
+      require you to allocate an empty struct so they can fill it in,
+      and then you can read the information out of it.</para>
+      <para>Also, some of them have their own structs and return a
+      pointer to that same struct every time you call them, but those
+      are easier to deal with, so they won't be covered in this
+      section.</para>
+      <para>You might know that Lisp (and, indeed, most programming
+      languages) has two separate regions of memory.  There's the
+      stack, which is where variable bindings are kept.  Memory on the
+      stack is allocated every time any function is called, and
+      deallocated when it returns, so it's useful for anything that
+      doesn't need to last longer than one function call, when there's
+      only one thread.  If that's all you need, you can do it with
+      .</para>
+      <para>Then, there's the heap, which holds everything else, and
+      is our subject here.  There are two advantages and one big
+      disadvantage to putting things on the heap rather than the
+      stack.  First, data allocated on the heap can be passed outside
+      of the scope in which it was created.  This is useful for data
+      which may need to be passed between multiple C calls or multiple
+      threads. Also, some data may be too large to copy multiple times
+      or may be too large to allocate on the stack.</para>
+      <para>The second advantage is security.  If incoming data is
+      being placed directly onto the stack, the input data can cause
+      stack overflows and underflows.  This is not something which
+      Lisp users generally worry about since garbage collection
+      generally handles memory management.  However, "stack smashing"
+      is one of the classic exploits in C which malicious hackers can
+      use to gain control of a machine.  Not checking external data is
+      always a bad idea; however, allocating it into the heap at least
+      offers more protection than direct stack allocation.</para>
+      <para>The big disadvantage to allocating data on the heap is
+      that it must be explicitly deallocated - you need to "free" it
+      when you're done with it.  Ordinarily, in Lisp, you wouldn't
+      allocate memory yourself, and the garbage collector would know
+      about it, so you wouldn't have to think about it again.  When
+      you're doing it manually, it's very different.  Memory
+      management becomes a manual process, just like in C and
+      C++.</para>
+      <para>What that means is that, if you allocate something and
+      then lose track of the pointer to it, there's no way to ever
+      free that memory.  That's what's called a memory leak, and if
+      your program leaks enough memory it will eventually use up all
+      of it!  So, you need to be careful to not lose your
+      pointers.</para>
       <para>That disadvantage, though, is also an advantage for using
-foreign functions.  Since the garbage collector doesn't know about
-this memory, it will never move it around.  External C code
-needs this, because it doesn't know how to follow it to where it
-moved, the way that Lisp code does.  If you allocate data manually,
-you can pass it to foreign code and know that no matter what that
-code needs to do with it, it will be able to, until you
-deallocated it.  Of course, you'd better be sure it's done before
-you do.  Otherwise, your program will be unstable and might crash
-sometime in the future, and you'll have trouble figuring out what
-caused
-the trouble, because there won't be anything pointing
-back and saying "you deallocated this too soon."</para>
+      foreign functions.  Since the garbage collector doesn't know
+      about this memory, it will never move it around.  External C
+      code needs this, because it doesn't know how to follow it to
+      where it moved, the way that Lisp code does.  If you allocate
+      data manually, you can pass it to foreign code and know that no
+      matter what that code needs to do with it, it will be able to,
+      until you deallocated it.  Of course, you'd better be sure it's
+      done before you do.  Otherwise, your program will be unstable
+      and might crash sometime in the future, and you'll have trouble
+      figuring out what caused the trouble, because there won't be
+      anything pointing back and saying "you deallocated this too
+      soon."</para>
       <para>And, so, on to the code...</para>
       <para>As in the last tutorial, our first step
-is to create a local dynamic library in order to help show
-what is actually going on between OpenMCL and C.  So, create the file
-ptrtest.c, with the following code:</para>
+      is to create a local dynamic library in order to help show
+      what is actually going on between OpenMCL and C.  So, create the file
+      ptrtest.c, with the following code:</para>
       <programlisting>
-#include <stdio.h>
+#include &lt;stdio.h&gt;
 =

 void reverse_int_array(int * data, unsigned int dataobjs)
 {
   int i, t;
 =

-  for(i=3D0; i<dataobjs/2; i++)
+  for(i=3D0; i&lt;dataobjs/2; i++)
     {
       t =3D *(data+i);
       *(data+i) =3D *(data+dataobjs-1-i);
@@ -6765,7 +9556,7 @@
   int *t;
   int i;
 =

-  for(i=3D0; i<ptrobjs/2; i++)
+  for(i=3D0; i&lt;ptrobjs/2; i++)
     {
       t =3D *(ptrs+i);
       *(ptrs+i) =3D *(ptrs+ptrobjs-1-i);
@@ -6781,26 +9572,27 @@
   reverse_int_array(*(ptrs+0), 4);
   reverse_int_array(*(ptrs+1), 4);
 }
-</programlisting>
-      <para>This defines three functions.  <literal>reverse_int_array</lit=
eral>
-takes a pointer to an array of <literal>int</literal>s, and a count
-telling how many items are in the array, and loops through it
-putting the elements in reverse.
-<literal>reverse_int_ptr_array</literal> does the same thing,
-but with an array of pointers to <literal>int</literal>s.  It only
-reverses the order the pointers are in; each pointer still points to
-the same thing.
-<literal>reverse_int_ptr_ptrtest</literal>
-takes an array of pointers to arrays of <literal>int</literal>s.  (With me=
?)
-It doesn't need to be told their sizes;
-it just assumes that the array of pointers has two items,
-and that both of those are arrays which have four items.  It
-reverses the array of pointers, then it reverses each of the two
-arrays of <literal>int</literal>s.</para>
-      <para>Now, compile ptrtest.c into a dynamic library using the comman=
d:</para>
+      </programlisting>
+      <para>This defines three functions.
+      <literal>reverse_int_array</literal> takes a pointer to an array
+      of <literal>int</literal>s, and a count telling how many items
+      are in the array, and loops through it putting the elements in
+      reverse.  <literal>reverse_int_ptr_array</literal> does the same
+      thing, but with an array of pointers to <literal>int</literal>s.
+      It only reverses the order the pointers are in; each pointer
+      still points to the same thing.
+      <literal>reverse_int_ptr_ptrtest</literal> takes an array of
+      pointers to arrays of <literal>int</literal>s.  (With me?)  It
+      doesn't need to be told their sizes; it just assumes that the
+      array of pointers has two items, and that both of those are
+      arrays which have four items.  It reverses the array of
+      pointers, then it reverses each of the two arrays of
+      <literal>int</literal>s.</para>
+      <para>Now, compile ptrtest.c into a dynamic library using the
+      command:</para>
       <programlisting>
 gcc -dynamiclib -Wall -o libptrtest.dylib ptrtest.c -install_name ./libptr=
test.dylib
-</programlisting>
+      </programlisting>
       <para>If that command doesn't make sense to you, feel free to go back
 and read about it at .</para>
       <para>Now, start OpenMCL and enter:</para>
@@ -6824,15 +9616,15 @@
      (setf ,mp nil)))
 DISPOSE-HEAP-IVECTOR
 </programlisting>
-      <para>You don't understand how those functions do what they do.  Tha=
t's
-okay; it gets into very fine detail which really doesn't matter,
-because you don't need to change them.</para>
-      <para>The function <literal>make-heap-ivector</literal> is the prima=
ry
-tool for
-allocating objects in heap memory.  It allocates a fixed-size OpenMCL
-object in heap memory.  It returns both an array reference, which can
-be used directly from OpenMCL, and a <literal>macptr</literal>, which can
-be used to access the underlying memory directly.  For example:</para>
+      <para>If you don't understand how those functions do what they do.
+      That's okay; it gets into very fine detail which really doesn't
+      matter, because you don't need to change them.</para>
+      <para>The function <literal>make-heap-ivector</literal> is the
+      primary tool for allocating objects in heap memory.  It
+      allocates a fixed-size OpenMCL object in heap memory.  It
+      returns both an array reference, which can be used directly from
+      OpenMCL, and a <literal>macptr</literal>, which can be used to
+      access the underlying memory directly.  For example:</para>
       <programlisting>
 ? ;; Create an array of 3 4-byte-long integers
 (multiple-value-bind (la lap)
@@ -6842,29 +9634,25 @@
 ;Compiler warnings :
 ;   Undeclared free variable A, in an anonymous lambda form.
 ;   Undeclared free variable AP, in an anonymous lambda form.
-#<A Mac Pointer #x10217C>
+#&lt;A Mac Pointer #x10217C>
 =

 ? a
 #(1396 2578 97862649)
 =

 ? ap
-#<A Mac Pointer #x10217C>
+#&lt;A Mac Pointer #x10217C>
 </programlisting>
       <para>It's important to realize that the contents of the
-<literal>ivector</literal> we've just created
-haven't been initialized,
-so their values are unpredictable,
-and you should be sure not to
-read from them before you set them, to avoid confusing results.</para>
-      <para>At this point, <literal>a</literal> references an object which
-works just
-like a normal array.  You can refer to any item of it with
-the standard <literal>aref</literal> function, and set them
-by combining that with <literal>setf</literal>.
-As noted
-above, the <literal>ivector</literal>'s
-contents haven't been initialized,
-so that's the next order of business:</para>
+      <literal>ivector</literal> we've just created haven't been
+      initialized, so their values are unpredictable, and you should
+      be sure not to read from them before you set them, to avoid
+      confusing results.</para>
+      <para>At this point, <literal>a</literal> references an object
+      which works just like a normal array.  You can refer to any item
+      of it with the standard <literal>aref</literal> function, and
+      set them by combining that with <literal>setf</literal>.  As
+      noted above, the <literal>ivector</literal>'s contents haven't
+      been initialized, so that's the next order of business:</para>
       <programlisting>
 ? a
 #(1396 2578 97862649)
@@ -6884,8 +9672,8 @@
 ? a
 #(3 4 5)
 </programlisting>
-      <para>In addition, the <literal>macptr</literal> allows direct acces=
s to the same
-memory:</para>
+      <para>In addition, the <literal>macptr</literal> allows direct
+      access to the same memory:</para>
       <programlisting>
 ? (setq *byte-length-of-long* 4)
 4
@@ -6905,42 +9693,41 @@
 ? ;; Show that a actually got changed through ap
 a
 #(6 4 7)
-</programlisting>
-      <para>So far, there is nothing about this object that could not be d=
one much
-better with standard Lisp.  However, the <literal>macptr</literal> can be
-used to pass this chunk of memory off to a C function.  Let's use
-the C
-code to reverse the elements in the array:</para>
+      </programlisting>
+      <para>So far, there is nothing about this object that could not
+      be done much better with standard Lisp.  However, the
+      <literal>macptr</literal> can be used to pass this chunk of
+      memory off to a C function.  Let's use the C code to reverse the
+      elements in the array:</para>
       <programlisting>
 ? ;; Insert the full path to your copy of libptrtest.dylib
 (open-shared-library "/Users/andrewl/openmcl/openmcl/gtk/libptrtest.dylib")
-#<SHLIB /Users/andrewl/openmcl/openmcl/gtk/libptrtest.dylib #x639D1E6>
+#&lt;SHLIB /Users/andrewl/openmcl/openmcl/gtk/libptrtest.dylib #x639D1E6>
 =

 ? a
 #(6 4 7)
 =

 ? ap
-#<A Mac Pointer #x10217C>
+#&lt;A Mac Pointer #x10217C>
 =

 ? (external-call "_reverse_int_array" :address ap :unsigned-int (length a)=
 :address)
-#<A Mac Pointer #x10217C>
+#&lt;A Mac Pointer #x10217C>
 =

 ? a
 #(7 4 6)
 =

 ? ap
-#<A Mac Pointer #x10217C>
+#&lt;A Mac Pointer #x10217C>
 </programlisting>
       <para>The array gets passed correctly to the C function,
-<literal>reverse_int_array</literal>.  The C function
-reverses the contents of the array in-place; that is, it doesn't make
-a new array, just keeps the same one and reverses what's in it.
-Finally, the C function
-passes control back to OpenMCL.  Since the allocated array memory has
-been directly modifed, OpenMCL reflects those changes directly in the
-array as well.</para>
-      <para>There is one final bit of housekeeping to deal with.  Before m=
oving
-on, the memory needs to be deallocated:</para>
+      <literal>reverse_int_array</literal>.  The C function reverses
+      the contents of the array in-place; that is, it doesn't make a
+      new array, just keeps the same one and reverses what's in it.
+      Finally, the C function passes control back to OpenMCL.  Since
+      the allocated array memory has been directly modifed, OpenMCL
+      reflects those changes directly in the array as well.</para>
+      <para>There is one final bit of housekeeping to deal with.
+      Before moving on, the memory needs to be deallocated:</para>
       <programlisting>
 ? ;; dispose-heap-ivector created for symmetry
 ;; Macro repeated here for pedagogy
@@ -6962,62 +9749,59 @@
 NIL
 </programlisting>
       <para>The <literal>dispose-heap-ivector</literal> macro actually
-deallocates the
-ivector, releasing its memory into the heap for something else to
-use.  In addition, it makes sure
-that the
-variables which it was called with are set to nil, because otherwise
-they would still be referencing the memory of the ivector - which is
-no longer allocated, so that would be a bug.  Making sure there are
-no other variables set to it is up to you.</para>
+      deallocates the ivector, releasing its memory into the heap for
+      something else to use.  In addition, it makes sure that the
+      variables which it was called with are set to nil, because
+      otherwise they would still be referencing the memory of the
+      ivector - which is no longer allocated, so that would be a bug.
+      Making sure there are no other variables set to it is up to
+      you.</para>
       <para>When do you call <literal>dispose-heap-ivector</literal>?
-Anytime after you know the ivector will never be used again, but no
-sooner.  If you have a lot of ivectors, say, in a hash table,
-you need to make sure that when whatever you were doing with the
-hash table is done, those ivectors all get freed.  Unless there's
-still something somewhere else which refers to them, of course!
-Exactly what strategy to take depends on the situation,
-so just try to keep things simple unless you know better.</para>
-      <para>The simplest situation is when you have things set up so that =
a Lisp
-object "encapsulates" a pointer to foreign data, taking care of all
-the
-details of using it.  In this case, you don't want those two things
-to have different lifetimes: You want to make sure your Lisp object
-exists as long as the foreign data does, and no longer; and you want
-to make sure the foreign data doesn't get deallocated while your
-Lisp object still refers to it.</para>
-      <para>If you're willing to accept a few limitations, you can make th=
is
-easy.  First, you can't let foreign code keep a permanent pointer
-to the
-memory; it has to always finish what it's doing, then return, and
-not refer to that memory again.  Second, you can't let any Lisp
-code that isn't part of your encapsulating "wrapper" refer to the
-pointer directly.  Third, nothing, either foreign code or Lisp
-code, should explicitly deallocate the memory.</para>
-      <para>If you can make sure all of these are true, you can at least
-ensure that the foreign
-pointer is deallocated when the encapsulating object is about to
-become
-garbage, by using OpenMCL's nonstandard "termination" mechanism,
-which is essentially the same as what Java and other languages
-call "finialization".</para>
-      <para>Termination is a way of asking the garbage collector to let yo=
u know
-when it's about to destroy an object which isn't used anymore.
-Before destroying the object, it calls a function which you write,
-called a terminator.</para>
+      Anytime after you know the ivector will never be used again, but
+      no sooner.  If you have a lot of ivectors, say, in a hash table,
+      you need to make sure that when whatever you were doing with the
+      hash table is done, those ivectors all get freed.  Unless
+      there's still something somewhere else which refers to them, of
+      course!  Exactly what strategy to take depends on the situation,
+      so just try to keep things simple unless you know better.</para>
+      <para>The simplest situation is when you have things set up so
+      that a Lisp object "encapsulates" a pointer to foreign data,
+      taking care of all the details of using it.  In this case, you
+      don't want those two things to have different lifetimes: You
+      want to make sure your Lisp object exists as long as the foreign
+      data does, and no longer; and you want to make sure the foreign
+      data doesn't get deallocated while your Lisp object still refers
+      to it.</para>
+      <para>If you're willing to accept a few limitations, you can
+      make this easy.  First, you can't let foreign code keep a
+      permanent pointer to the memory; it has to always finish what
+      it's doing, then return, and not refer to that memory again.
+      Second, you can't let any Lisp code that isn't part of your
+      encapsulating "wrapper" refer to the pointer directly.  Third,
+      nothing, either foreign code or Lisp code, should explicitly
+      deallocate the memory.</para>
+      <para>If you can make sure all of these are true, you can at
+      least ensure that the foreign pointer is deallocated when the
+      encapsulating object is about to become garbage, by using
+      OpenMCL's nonstandard "termination" mechanism, which is
+      essentially the same as what Java and other languages call
+      "finialization".</para>
+      <para>Termination is a way of asking the garbage collector to
+      let you know when it's about to destroy an object which isn't
+      used anymore.  Before destroying the object, it calls a function
+      which you write, called a terminator.</para>
       <para>So, you can use termination to find out when a particular
-<literal>macptr</literal> is about to become garbage.
-That's not quite
-as helpful as it might seem:  It's not exactly the same thing as
-knowing that the block of memory it points to is unreferenced.
-For example, there could be another <literal>macptr</literal> somewhere
-to the
-same block; or, if it's a struct, there could be a
-<literal>macptr</literal> to one of its fields.  Most problematically,
-if the address of that memory has been passed to foreign code,
-it's sometimes hard to know whether that code has kept the
-pointer.  Most foreign functions don't, but it's not hard to think of
-exceptions.</para>
+      <literal>macptr</literal> is about to become garbage.  That's
+      not quite as helpful as it might seem: It's not exactly the same
+      thing as knowing that the block of memory it points to is
+      unreferenced.  For example, there could be another
+      <literal>macptr</literal> somewhere to the same block; or, if
+      it's a struct, there could be a <literal>macptr</literal> to one
+      of its fields.  Most problematically, if the address of that
+      memory has been passed to foreign code, it's sometimes hard to
+      know whether that code has kept the pointer.  Most foreign
+      functions don't, but it's not hard to think of
+      exceptions.</para>
       <para>You can use code such as this to make all this happen:</para>
       <programlisting>
 (defclass wrapper (whatever)
@@ -7042,791 +9826,1369 @@
       (dispose-heap-ivector ivector macptr)
       (setq ivector nil
             macptr nil))))
-</programlisting>
-      <para>The <literal>ccl:terminate</literal> method will be called on
-some arbitrary thread
-sometime (hopefully soon) after the GC has decided that there are no
-strong references to an object which has been the argument of a
-<literal>ccl:terminate-when-unreachable</literal> call.</para>
-      <para>If it makes sense to say that the foreign object should live a=
s long
-as there's Lisp code that references it (through the encapsulating
-obect) and no longer, this is one way of doing that.</para>
-      <para>Now we've covered passing basic types back and forth with C, a=
nd
-we've done the same with pointers.  You may think this is all...
-but we've only done pointers to basic types.  Join us next time
-for pointers... to pointers.</para>
+      </programlisting>
+      <para>The <literal>ccl:terminate</literal> method will be called
+      on some arbitrary thread sometime (hopefully soon) after the GC
+      has decided that there are no strong references to an object
+      which has been the argument of a
+      <literal>ccl:terminate-when-unreachable</literal> call.</para>
+      <para>If it makes sense to say that the foreign object should
+      live as long as there's Lisp code that references it (through
+      the encapsulating obect) and no longer, this is one way of doing
+      that.</para>
+      <para>Now we've covered passing basic types back and forth with
+      C, and we've done the same with pointers.  You may think this is
+      all...  but we've only done pointers to basic types.  Join us
+      next time for pointers... to pointers.</para>
 =

       <sect2 id=3D"Acknowledgement--1-">
-        <para>Acknowledgement
-Much of this chapter was generously contributed by
-Andrew P. LentvorskiJr.</para>
+	<title>Acknowledgement</title>
+	<para>Much of this chapter was generously contributed by
+	Andrew P. Lentvorski Jr.</para>
       </sect2>
     </sect1>
 =

-    <sect1 id=3D"The-Foreign-Function-Interface-Dictionary">
-      <para>The Foreign-Function-Interface Dictionary</para>
-
-      <sect2 id=3D"DEF-FOREIGN-TYPE">
-        <para>DEF-FOREIGN-TYPE</para>
-        <informalfigure>def-foreign-type</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>DEF-FOREIGN-TYPE &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    def-foreign-type name foreign-type-spec
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>NIL or a keyword; the keyword may containescapin=
g constructs (see ).</variablelist>
-          </indexterm><indexterm>foreign-type-spec
-            <variablelist>A foreign type specifier, whose syntax is (loose=
ly)defined above.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>If name is non-NIL, defines name to be an alias for the
-foreign type specified by foreign-type-spec. If foreign-type-spec
-is a named structure or union type, additionally defines that
-structure or union type.</para>
-        <para>If name is NIL, foreign-type-spec must be a named foreign
-struct or union definition, in which case the foreign structure
-or
-union definition is put in effect.</para>
-        <para>Note that there are two separate namespaces for foreign
-type names, one for the names of ordinary types and one for
-the names of structs and unions.  Which one
-<literal>name</literal> refers to depends on
-<literal>foreign-type-spec</literal> in the obvious manner.</para>
-      </sect2>
-
-      <sect2 id=3D"MAKE-RECORD">
-        <para>MAKE-RECORD</para>
-        <informalfigure>make-record</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>MAKE-RECORD &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    make-record typespec
-	    &amp;rest initforms =3D> result
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>typespec
-            <variablelist>A foreign type specifier, or a keyword which is =
usedas the name of a foreign struct or union.</variablelist>
-          </indexterm><indexterm>initforms
-            <variablelist>If the type denoted by <literal>typespec</litera=
l>is scalar, a single value appropriate for that type;otherwise, a list of =
alternating field names andvalues appropriate for the types of those fields=
.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>A <literal>macptr</literal> which encapsulates t=
he address of anewly-allocated record on the foreign heap.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Expands into code which allocates and initalizes
-an instance of the type
-denoted by <literal>typespec</literal>, on the foreign
-heap.  The record is allocated using the C function
-<literal>malloc</literal>, and the user of
-<literal>make-record</literal> must explicitly call
-the C function <literal>free</literal> to deallocate the
-record, when it is no longer needed.</para>
-        <para>If <literal>initforms</literal> is provided, its value
-or values are used in the initialization.  When the type
-is a scalar, <literal>initforms</literal> is either a single
-value which can be coerced to that type, or no value, in which
-case binary 0 is used.  When the type is a <literal>struct</literal>,
-<literal>initforms</literal> is a list, giving field names
-and the values for each.  Each field is treated in the same way
-as a scalar is: If a value for it is given, it must be
-coerceable to the field's type; if not, binary 0 is used.</para>
-        <para>When the type is an array, <literal>initforms</literal> may
-not be provided, because <literal>make-record</literal>
-cannot initialize its values.  <literal>make-record</literal>
-is also unable to initialize fields of a <literal>struct</literal>
-which are themselves
-<literal>struct</literal>s.  The user of
-<literal>make-record</literal> should set these values
-by another means.</para>
-        <para>A possibly-significant limitation is that it must be possibl=
e to
-find the foreign type at the time the macro is expanded;
-<literal>make-record</literal> signals an error if this is
-not the case.</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para>It is inconvenient that <literal>make-record</literal> is a
-macro, because this means that <literal>typespec</literal>
-cannot be a variable; it must be an immediate value.</para>
-        <para>If it weren't for this requirement,
-<literal>make-record</literal> could be a function.  However,
-that would mean that any stand-alone application using it would
-have to include a copy of the interface database
-(see The Interface Database), which is undesireable
-because it's large.</para>
-      </sect2>
-
-      <sect2 id=3D"RLET">
-        <para>RLET</para>
-        <informalfigure>rlet</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>RLET &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    rlet (var typespec &amp;rest initforms)*
-	    &amp;body body
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>var
-            <variablelist>A symbol (a lisp variable)</variablelist>
-          </indexterm><indexterm>typespec
-            <variablelist>A foreign type specifier or foreign record name.=
</variablelist>
-          </indexterm><indexterm>initforms
-            <variablelist>As described above, for</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Executes <literal>body</literal>
-in an environment in which each var is bound
-to a MACPTR (see ) encapsulating the
-address of a stack-allocated foreign memory block, allocated and
-initialized from typespec and initforms as per
-.
-Returns whatever value(s) <literal>body</literal>
-returns.</para>
-        <para>Record fields that aren't explicitly initialized have
-unspecified contents.</para>
-      </sect2>
-
-      <sect2 id=3D"RLETZ">
-        <para>RLETZ</para>
-        <informalfigure>rletz</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>RLETZ &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    rletz (var typespec &amp;rest initforms)*
-	    &amp;body body
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>var
-            <variablelist>A symbol (a lisp variable)</variablelist>
-          </indexterm><indexterm>typespec
-            <variablelist>A foreign type specifier or foreign record name.=
</variablelist>
-          </indexterm><indexterm>initforms
-            <variablelist>As described above, for ccl:make-record</variabl=
elist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Executes body in an environment in which each var is bound
-to a MACPTR (see ) encapuslating the
-address of a stack-allocated foreign memory block, allocated and
-initialized from typespec and initforms as
-ccl:make-record.</para>
-        <para>Returns whatever value(s) body returns.</para>
-        <para>Unlike rlet, record fields that aren't explicitly
-initialized are set to binary 0.</para>
-      </sect2>
-
-      <sect2 id=3D"PREF">
-        <para>PREF</para>
-        <informalfigure>pref</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>PREF &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    pref ptr accessor-form
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>ptr
-            <variablelist>a MACPTR (see ).</variablelist>
-          </indexterm><indexterm>accessor-form
-            <variablelist>a keyword which names a foreign type or record, =
asdescribed in .</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>References an instance of a foreign type (or a component of
-a foreign type) accessible via ptr.</para>
-        <para>Expands into code which references the indicated scalar type
-or component, or returns a pointer to a composite type.</para>
-        <para>PREF can be used with SETF.</para>
-        <para>RREF is a deprecated alternative to PREF. It accepts a
-:STORAGE keyword and rather loudly ignores it.</para>
-      </sect2>
-
-      <sect2 id=3D"OPEN-SHARED-LIBRARY">
-        <para>OPEN-SHARED-LIBRARY</para>
-        <informalfigure>open-shared-library</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>OPEN-SHARED-LIBRARY &mdash; Asks the operating system to loa=
d a shared library
-for OpenMCL to use.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    open-shared-library name =3D> library
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>A SIMPLE-STRING which is presumed to be the so-n=
ame ofor a filesystem path to the library.</variablelist>
-          </indexterm><indexterm>library
-            <variablelist>An object of type SHLIB which describes thelibra=
ry denoted by <literal>name</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>If the library denoted by <literal>name</literal> can
-be loaded by the
-operating system, returns an object of type SHLIB that describes
-the library; if the library is already open, increments a
-reference count. If the library can't be loaded, signals a
-SIMPLE-ERROR which contains an often-cryptic message from the
-operating system.</para>
-        <bridgehead renderas=3D"sect3">Examples</bridgehead>
-        <programlisting>
-;;; Try to do something simple.
-? (open-shared-library "libgtk.so")
-> Error: Error opening shared library "libgtk.so": /usr/lib/libgtk.so: und=
efined symbol: gdk_threads_mutex
-> While executing: OPEN-SHARED-LIBRARY
-
-;;; Grovel around, curse, and try to find out where "gdk_threads_mutex"
+    <sect1>
+      <title>The Foreign-Function-Interface Dictionary</title>
+        =

+      <refentry id=3D"m_def-foreign-type">
+	<indexterm zone=3D"m_def-foreign-type">
+	  <primary>def-foreign-type</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>DEF-FOREIGN-TYPE</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>def-foreign-type</function> name foreign-type-spec
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>name</term>
+	      =

+	      <listitem>
+		<para>NIL or a keyword; the keyword may contain
+		<link linkend=3D"arb30">escaping constructs</link>.</para>
+	      </listitem>
+	    </varlistentry>
+	    =

+	    <varlistentry>
+	      <term>foreign-type-spec</term>
+	      =

+	      <listitem>
+		<para>A foreign type specifier, whose syntax is (loosely)
+		defined above.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>If name is non-NIL, defines name to be an alias for the
+	  foreign type specified by foreign-type-spec. If foreign-type-spec
+	  is a named structure or union type, additionally defines that
+	  structure or union type.</para>
+	  =

+	  <para>If name is NIL, foreign-type-spec must be a named foreign
+	  struct or union definition, in which case the foreign structure
+	  or
+	  union definition is put in effect.</para>
+	  =

+	  <para>Note that there are two separate namespaces for foreign
+	  type names, one for the names of ordinary types and one for
+	  the names of structs and unions.  Which one
+	  <varname>name</varname> refers to depends on
+	  <varname>foreign-type-spec</varname> in the obvious manner.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_make-record">
+	<indexterm zone=3D"m_make-record">
+	  <primary>make-record</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>MAKE-RECORD</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>make-record</function> typespec
+	    &rest; initforms =3D> result
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>typespec</term>
+
+	      <listitem>
+		<para>A foreign type specifier, or a keyword which is used
+		as the name of a foreign struct or union.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>initforms</term>
+
+	      <listitem>
+		<para>If the type denoted by <varname>typespec</varname>
+		is scalar, a single value appropriate for that type;
+		otherwise, a list of alternating field names and
+		values appropriate for the types of those fields.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>result</term>
+
+	      <listitem>
+		<para>
+		  A <type>macptr</type> which encapsulates the address of a
+		  newly-allocated record on the foreign heap.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>
+	    Expands into code which allocates and initalizes
+	    an instance of the type =

+	    denoted by <varname>typespec</varname>, on the foreign
+	    heap.  The record is allocated using the C function
+	    <function>malloc</function>, and the user of
+	    <function>make-record</function> must explicitly call
+	    the C function <function>free</function> to deallocate the
+	    record, when it is no longer needed.
+	  </para>
+
+	  <para>
+	    If <varname>initforms</varname> is provided, its value
+	    or values are used in the initialization.  When the type
+	    is a scalar, <varname>initforms</varname> is either a single
+	    value which can be coerced to that type, or no value, in which
+	    case binary 0 is used.  When the type is a <type>struct</type>,
+	    <varname>initforms</varname> is a list, giving field names
+	    and the values for each.  Each field is treated in the same way
+	    as a scalar is: If a value for it is given, it must be
+	    coerceable to the field's type; if not, binary 0 is used.
+	  </para>
+
+	  <para>
+	    When the type is an array, <varname>initforms</varname> may
+	    not be provided, because <function>make-record</function>
+	    cannot initialize its values.  <function>make-record</function>
+	    is also unable to initialize fields of a <type>struct</type>
+	    which are themselves
+	    <type>struct</type>s.  The user of
+	    <function>make-record</function> should set these values
+	    by another means.
+	  </para>
+
+	  <para>
+	    A possibly-significant limitation is that it must be possible to
+	    find the foreign type at the time the macro is expanded;
+	    <function>make-record</function> signals an error if this is
+	    not the case.
+	  </para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>
+	    It is inconvenient that <function>make-record</function> is a
+	    macro, because this means that <varname>typespec</varname>
+	    cannot be a variable; it must be an immediate value.
+	  </para>
+	    =

+	  <para>
+	    If it weren't for this requirement,
+	    <function>make-record</function> could be a function.  However,
+	    that would mean that any stand-alone application using it would
+	    have to include a copy of the interface database
+	    (see <xref linkend=3D"arb25"/>), which is undesireable
+	    because it's large.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_rlet">
+	<indexterm zone=3D"m_rlet">
+	  <primary>rlet</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>RLET</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>rlet</function> (var typespec &rest; initforms)*
+	    &body; body
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>var</term>
+
+	      <listitem>
+		<para>A symbol (a lisp variable)</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>typespec</term>
+
+	      <listitem>
+		<para>A foreign type specifier or foreign record name.</para>
+	      </listitem>
+	    </varlistentry>
+
+ <varlistentry>
+	      <term>initforms</term>
+
+	      <listitem>
+		<para>As described above, for
+		<xref linkend=3D"m_make-record"/></para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Executes <varname>body</varname>
+	  in an environment in which each var is bound
+	  to <link linkend=3D"Referencing-and-Using-Foreign-Memory-Addresses">a M=
ACPTR</link> encapsulating the
+	  address of a stack-allocated foreign memory block, allocated and
+	  initialized from typespec and initforms as per
+	  <xref linkend=3D"m_make-record"/>.
+	  Returns whatever value(s) <varname>body</varname>
+	  returns.</para>
+	  =

+	  <para>Record fields that aren&#39;t explicitly initialized have
+	  unspecified contents.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_rletz">
+	<indexterm zone=3D"m_rletz">
+	  <primary>rletz</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>RLETZ</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>rletz</function> (var typespec &rest; initforms)*
+	    &body; body
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>var</term>
+
+	      <listitem>
+		<para>A symbol (a lisp variable)</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>typespec</term>
+
+	      <listitem>
+		<para>A foreign type specifier or foreign record name.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>initforms</term>
+
+	      <listitem>
+		<para>As described above, for ccl:make-record</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Executes body in an environment in which each var is
+	  bound to <link
+	  linkend=3D"Referencing-and-Using-Foreign-Memory-Addresses">a
+	  MACPTR</link> encapuslating the address of a stack-allocated
+	  foreign memory block, allocated and initialized from
+	  typespec and initforms as ccl:make-record.</para>
+	  =

+	  <para>Returns whatever value(s) body returns.</para>
+
+	  <para>Unlike rlet, record fields that aren&#39;t explicitly
+	  initialized are set to binary 0.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_pref">
+	<indexterm zone=3D"m_pref">
+	  <primary>pref</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>PREF</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>pref</function> ptr accessor-form
+	  </synopsis>
+
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>ptr</term>
+
+	      <listitem>
+		<para><link linkend=3D"Referencing-and-Using-Foreign-Memory-Addresses">a=
 MACPTR</link>.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>accessor-form</term>
+
+	      <listitem>
+		<para>a keyword which names a foreign type or record, as
+		described in <xref linkend=3D"arb45"/>.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>References an instance of a foreign type (or a component of
+	  a foreign type) accessible via ptr.</para>
+	  =

+	  <para>Expands into code which references the indicated scalar type
+	  or component, or returns a pointer to a composite type.</para>
+	  =

+	  <para>PREF can be used with SETF.</para>
+	  =

+	  <para>RREF is a deprecated alternative to PREF. It accepts a
+	  :STORAGE keyword and rather loudly ignores it.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_open-shared-library">
+	<indexterm zone=3D"f_open-shared-library">
+	  <primary>open-shared-library</primary>
+	</indexterm>
+	=

+	<refnamediv>
+	  <refname>OPEN-SHARED-LIBRARY</refname>
+	  <refpurpose>Asks the operating system to load a shared library
+	  for OpenMCL to use.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+	=

+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>open-shared-library</function> name =3D> library
+	  </synopsis>
+	</refsynopsisdiv>
+	=

+	<refsect1>
+	  <title>Values</title>
+	  =

+	  <variablelist>
+	    <varlistentry>
+	      <term>name</term>	=

+	      <listitem>
+		<para>A SIMPLE-STRING which is presumed to be the so-name of
+		or a filesystem path to the library.</para>
+	      </listitem>
+	    </varlistentry>
+	    =

+	    <varlistentry>
+	      <term>library</term>
+	      <listitem>
+		<para>An object of type SHLIB which describes the
+		library denoted by <varname>name</varname>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+	=

+	<refsect1>
+	  <title>Description</title>
+
+	  <para>If the library denoted by <varname>name</varname> can
+	  be loaded by the
+	  operating system, returns an object of type SHLIB that describes
+	  the library; if the library is already open, increments a
+	  reference count. If the library can&#39;t be loaded, signals a
+	  SIMPLE-ERROR which contains an often-cryptic message from the
+	  operating system.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Examples</title>
+
+	  <programlisting format=3D"linespecific">;;; Try to do something simple.
+? (open-shared-library &#34;libgtk.so&#34;)
+&#62; Error: Error opening shared library &#34;libgtk.so&#34;: /usr/lib/li=
bgtk.so: undefined symbol: gdk_threads_mutex
+&#62; While executing: OPEN-SHARED-LIBRARY
+
+;;; Grovel around, curse, and try to find out where &#34;gdk_threads_mutex=
&#34;
 ;;; might be defined. Then try again:
 =

-? (open-shared-library "libgdk.so")
-#<SHLIB libgdk.so #x3046DBB6>
-
-? (open-shared-library "libgtk.so")
-#<SHLIB libgtk.so #x3046DC86>
+? (open-shared-library &#34;libgdk.so&#34;)
+#&#60;SHLIB libgdk.so #x3046DBB6&#62;
+
+? (open-shared-library &#34;libgtk.so&#34;)
+#&#60;SHLIB libgtk.so #x3046DC86&#62;
 =

 ;;; Reference an external symbol defined in one of those libraries.
 =

-? (external "gtk_main")
-#<EXTERNAL-ENTRY-POINT "gtk_main" (#x012C3004) libgtk.so #x3046FE46>
+? (external &#34;gtk_main&#34;)
+#&#60;EXTERNAL-ENTRY-POINT &#34;gtk_main&#34; (#x012C3004) libgtk.so #x304=
6FE46&#62;
 =

 ;;; Close those libraries.
 =

-? (close-shared-library "libgtk.so")
+? (close-shared-library &#34;libgtk.so&#34;)
 T
 =

-? (close-shared-library "libgdk.so")
+? (close-shared-library &#34;libgdk.so&#34;)
 T
 =

 ;;; Reference the external symbol again.
 =

-? (external "gtk_main")
-#<EXTERNAL-ENTRY-POINT "gtk_main" {unresolved} libgtk.so #x3046FE46>
-</programlisting>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para>It would be helpful to describe what an soname is and give
-examples of one.</para>
-        <para>Does the SHLIB still get returned if the library is
-already open?</para>
-      </sect2>
-
-      <sect2 id=3D"CLOSE-SHARED-LIBRARY">
-        <para>CLOSE-SHARED-LIBRARY</para>
-        <informalfigure>close-shared-library</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CLOSE-SHARED-LIBRARY &mdash; Stops using a shared library, i=
nforming the operating
-system that it can be unloaded if appropriate.</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    close-shared-library library &amp;key
-	  completely
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>library
-            <variablelist>either an object of type SHLIB, or a string whic=
hdesignates one by its so-name.</variablelist>
-          </indexterm><indexterm>completely
-            <variablelist>a boolean.  The default is T.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>If <literal>completely</literal> is T, sets the
-reference count of <literal>library</literal> to 0.  Otherwise,
-decrements it by 1.  In either case, if the reference count
-becomes 0, <literal>close-shared-library</literal>
-frees all memory resources consumed <literal>library</literal>
-and
-causes any EXTERNAL-ENTRY-POINTs known to be defined by it to
-become unresolved.</para>
-      </sect2>
-
-      <sect2 id=3D"EXTERNAL">
-        <para>EXTERNAL</para>
-        <informalfigure>external</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>EXTERNAL &mdash; Resolves a reference to an external symbol =
which
-is defined in a shared library.</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    external name =3D> entry
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>a simple-string which names an external symbol.C=
ase-sensitive.</variablelist>
-          </indexterm><indexterm>entry
-            <variablelist>an object of type EXTERNAL-ENTRY-POINT which mai=
ntainsthe address of the foreign symbol named by<literal>name</literal>.</v=
ariablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>If there is already an EXTERNAL-ENTRY-POINT for
-the symbol named by <literal>name</literal>, finds it and
-returns it.  If not, creates one and returns it.</para>
-        <para>Tries to resolve the entry point to a memory address,
-and identify the containing library.</para>
-        <para>Be aware that under Darwin, external functions which
-are callable from C have underscores prepended to their names,
-as in "_fopen".</para>
-      </sect2>
-
-      <sect2 id=3D"iFF-CALL">
-        <para>%FF-CALL</para>
-        <informalfigure>%ff-call</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>%FF-CALL &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    %ff-call entrypoint
-	    {arg-type-keyword arg}* &amp;optional result-type-keyword
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>entrypoint
-            <variablelist>A fixnum or MACPTR</variablelist>
-          </indexterm><indexterm>arg-type-keyword
-            <variablelist>One of the foreign argument-type keywords, descr=
ibedabove</variablelist>
-          </indexterm><indexterm>arg
-            <variablelist>A lisp value of type indicated by the correspond=
ingarg-type-keyword</variablelist>
-          </indexterm><indexterm>result-type-keyword
-            <variablelist>One of the foreign argument-type keywords, descr=
ibedabove</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Calls the foreign function at address entrypoint passing the
-values of each arg as a foreign argument of type indicated by the
-corresponding arg-type-keyword. Returns the foreign function
-result (coerced to a Lisp object of type indicated by
-result-type-keyword), or NIL if result-type-keyword is :VOID or
-NIL</para>
-      </sect2>
-
-      <sect2 id=3D"FF-CALL">
-        <para>FF-CALL</para>
-        <informalfigure>ff-call</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>FF-CALL &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    ff-call entrypoint
-	    {arg-type-specifier arg}* &amp;optional result-type-specifier
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>entrypoint
-            <variablelist>A fixnum or MACPTR</variablelist>
-          </indexterm><indexterm>arg-type-specifer
-            <variablelist>One of the foreign argument-type keywords, descr=
ibedabove, or an equivalent foreigntype specifier (see ).</variablelist>
-          </indexterm><indexterm>arg
-            <variablelist>A lisp value of type indicated by the correspond=
ingarg-type-specifier</variablelist>
-          </indexterm><indexterm>result-type-specifier
-            <variablelist>One of the foreign argument-type keywords, descr=
ibedabove, or an equivalent foreigntype specifier (see ).</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Calls the foreign function at address entrypoint passing the
-values of each arg as a foreign argument of type indicated by the
-corresponding arg-type-specifier. Returns the foreign function
-result (coerced to a Lisp object of type indicated by
-result-type-specifier), or NIL if result-type-specifer is :VOID or
-NIL</para>
-      </sect2>
-
-      <sect2 id=3D"iREFERENCE-EXTERNAL-ENTRY-POINT">
-        <para>%REFERENCE-EXTERNAL-ENTRY-POINT</para>
-        <informalfigure>%reference-external-entry-point</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>%REFERENCE-EXTERNAL-ENTRY-POINT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    %reference-external-entry-point eep
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>eep
-            <variablelist>An EXTERNAL-ENTRY-POINT, as obtained by the EXTE=
RNALmacro.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Tries to resolve the address of the EXTERNAL-ENTRY-POINT
-eep; returns a fixnum representation of that address if
-successful, else signals an error.</para>
-      </sect2>
-
-      <sect2 id=3D"EXTERNAL-CALL">
-        <para>EXTERNAL-CALL</para>
-        <informalfigure>external-call</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>EXTERNAL-CALL &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    external-call name
-	    {arg-type-specifier arg}* &amp;optional result-type-specifier
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>A lisp string. See external, above.</variablelis=
t>
-          </indexterm><indexterm>arg-type-specifer
-            <variablelist>One of the foreign argument-type keywords, descr=
ibedabove, or an equivalent foreigntype specifier (see ).</variablelist>
-          </indexterm><indexterm>arg
-            <variablelist>A lisp value of type indicated by the correspond=
ingarg-type-specifier</variablelist>
-          </indexterm><indexterm>result-type-specifier
-            <variablelist>One of the foreign argument-type keywords, descr=
ibedabove, or an equivalent foreigntype specifier (see ).</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Calls the foreign function at the address obtained by
-resolving the external-entry-point associated with name, passing
-the values of each arg as a foreign argument of type indicated by
-the corresponding arg-type-specifier. Returns the foreign function
-result (coerced to a Lisp object of type indicated by
-result-type-specifier), or NIL if result-type-specifer is :VOID or
-NIL</para>
-      </sect2>
-
-      <sect2 id=3D"FOREIGN-SYMBOL-ENTRY">
-        <para>FOREIGN-SYMBOL-ENTRY</para>
-        <informalfigure>foreign-symbol-entry</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>FOREIGN-SYMBOL-ENTRY &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    foreign-symbol-entry name
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>A lisp string.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Tries to resolve the address of the foreign symbol name. If
-successful, returns a fixnum representation of that address, else
-returns NIL.</para>
-      </sect2>
-
-      <sect2 id=3D"FOREIGN-SYMBOL-ADDRESS">
-        <para>FOREIGN-SYMBOL-ADDRESS</para>
-        <informalfigure>foreign-symbol-address</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>FOREIGN-SYMBOL-ADDRESS &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    foreign-symbol-address name
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>A lisp string.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Tries to resolve the address of the foreign symbol name. If
-successful, returns that address encapsulated
-in a MACPTR (see ), else returns
-NIL.</para>
-      </sect2>
-
-      <sect2 id=3D"DEFCALLBACK">
-        <para>DEFCALLBACK</para>
-        <informalfigure>defcallback</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>DEFCALLBACK &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    defcallback name
-	    ({arg-type-specifier var}* &amp;optional result-type-specifier)
-	    &amp;body body
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>A symbol which can be made into a special variab=
le</variablelist>
-          </indexterm><indexterm>arg-type-specifer
-            <variablelist>One of the foreign argument-type keywords, descr=
ibedabove, or an equivalent foreigntype specifier (see ).In addition, if th=
e keyword:WITHOUT-INTERRUPTS is specified, the callback will beexecuted wit=
h lisp interrupts disabled if the correspondingvar is non-NIL. If :WITHOUT-=
INTERRUPTS is specified morethan once, the rightmost instance wins.</variab=
lelist>
-          </indexterm><indexterm>var
-            <variablelist>A symbol (lisp variable), which will be bound to=
 avalue of the specified type.</variablelist>
-          </indexterm><indexterm>body
-            <variablelist>A sequence of lisp forms, which should return a =
valuewhich can be coerced to the specified result-type.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Proclaims <literal>name</literal>
-to be a special variable; sets its value to a
-MACPTR which, when called by foreign code, calls a lisp function
-which expects foreign arguments of the specified types and which
-returns a foreign value of the specified result type. Any argument
-variables which correspond to foreign arguments of type :ADDRESS
-are bound to stack-allocated MACPTRs.</para>
-        <para>If <literal>name</literal>
-is already a callback function pointer, its value is
-not changed; instead, it's arranged
-that an
-updated version of the lisp callback function will be called.
-This feature allows for callback functions to be redefined
-incrementally, just like Lisp functions are.</para>
-        <para><literal>defcallback</literal>
-returns the callback pointer, e.g., the
-value of <literal>name</literal>.</para>
-      </sect2>
-
-      <sect2 id=3D"SHARP-UNDERSCORE">
-        <para>SHARP-AMPERSAND</para>
-        <informalfigure>#_</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>#_ &mdash;</para>
-        <para>Reader Macro</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Reads a symbol from the current input stream, with *PACKAGE*
-bound to the "OS" package and with readtable-case preserved.</para>
-        <para>Does a lookup on that symbol
-in the OpenMCL interface database (see ),
-signalling
-an error if no foreign function information can be found for the
-symbol in any
-active interface directory (see ).</para>
-        <para>Notes the foreign function information, including the foreign
-function's return type, the number and type of the foreign
-function's required arguments, and an indication of whether or
-not the function accepts additional arguments (via e.g., the
-"varargs" mechanism in C).</para>
-        <para>Defines a macroexpansion function on the symbol, which expand
-macro calls involving the symbol into EXTERNAL-CALL forms where
-foreign argument type specifiers for required arguments and the
-return value specifer are provided from the information ind the
-database.</para>
-        <para>Returns the symbol.</para>
-        <para>The effect of these steps is that it's possible to call
-foreign functions that take fixed numbers of arguments by simply
-providing argument values, as in:</para>
-        <programlisting>
-(#_isatty fd)
-(#_read fd buf n)
-</programlisting>
-        <para>and to call foreign functions that take variable numbers of
-arguments by specifying the types of non-required args, as in:</para>
-        <programlisting>
-(with-cstrs ((format-string "the answer is: %d"))
-  (#_printf format-string :int answer))
-</programlisting>
-      </sect2>
-
-      <sect2 id=3D"SHARP-AMPERSAND">
-        <para>SHARP-AMPERSAND</para>
-        <informalfigure>SHARP-AMPERSAND</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>#&amp; &mdash;</para>
-        <para>Reader Macro</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>In OpenMCL 1.0 and later, the #&amp; reader macro <tip><para=
>This
-functionality was introduced as #? in 0.14.2, but ANSI CL requires
-that #? be reserved for the user.  #? is still supported as an alias
-to #&amp;, but that will change in the next release.</para></tip> can be u=
sed to
-access foreign variables; this functionality depends on the presence
-of "vars.cdb" files in the interface database. The current behavior of
-the #&amp; reader macro is to:</para>
-        <para>Read a symbol from the current input stream, with *PACKAGE*
-bound to the "OS" package and with readtable-case preserved.</para>
-        <para>Use that symbol's pname to access the OpenMCL interface
-database, signalling an error if no appropriate foreign variable
-information can be found with that name in any active interface
-directory.</para>
-        <para>Use type information recorded in the database to construct a
-form which can be used to access the foreign variable, and return
-that form.</para>
-        <para>Please note that the set of foreign variables declared in he=
ader files
-may or may not match the set of foreign variables exported from
-libraries (we're generally talking about C and Unix here ...). When
-they do match, the form constructed by the #&amp; reader macro manages the
-details of resolving and tracking changes to the foreign variable's
-address.</para>
-        <para>Future extensions (via prefix arguments to the reader macro)=
 may
-offer additional behavior; it might be convenient (for instance) to be
-able to access the address of a foreign variable without dereferencing
-that address.</para>
-        <para>Foreign variables in C code tend to be platform- and
-package-specific (the canonical example - "errno" - is typically
-not a variable when threads are involved. )</para>
-        <para>In LinuxPPC,</para>
-        <programlisting>
-? #&amp;stderr
-</programlisting>
-        <para>returns a pointer to the stdio error stream ("stderr" is a
-macro under OSX/Darwin).</para>
-        <para>On both LinuxPPC and DarwinPPC,</para>
-        <programlisting>
-? #&amp;sys_errlist
-</programlisting>
-        <para>returns a pointer to a C array of C error message strings.</=
para>
-      </sect2>
-
-      <sect2 id=3D"USE-INTERFACE-DIR">
-        <para>USE-INTERFACE-DIR</para>
-        <informalfigure>use-interface-dir</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>USE-INTERFACE-DIR &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    use-interface-dir dir-id
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>dir-id
-            <variablelist>A keyword whose pname, mapped to lower case, nam=
es asubdirectory of "ccl:headers;" (or"ccl:darwin-headers;")</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Tells OpenMCL to add the interface directory denoted by
-dir-id to the list of interface directories which it consults for
-foreign type and function information. Arranges that that
-directory is searched before any others.</para>
-        <para>Note that <literal>use-interface-dir</literal>
-merely adds an entry
-to a search list.
-If the named directory doesn't exist in the file system
-or doesn't
-contain a set of database files, a runtime error may occur
-when OpenMCL
-tries to open some database file in that directory, and it
-will try to
-open such a database file whenever it needs to find any
-foreign type or
-function information. =

-may come in
-handy in that case.</para>
-        <bridgehead renderas=3D"sect3">Examples</bridgehead>
-        <para>One typically wants interface information to be
-available at compile-time (or, in many cases, at read-time).
-A typical idiom would be:</para>
-        <programlisting>
-(eval-when (:compile-toplevel :execute)
-  (use-interface-dir :GTK))
-</programlisting>
-        <para>Using the :GTK interface directory makes available
-information on
-foreign types, functions, and constants.  It's generally
-necessary to
-load foreign libraries before actually calling the
-foreign code, which for GTK can be done like this:</para>
-        <programlisting>
-(load-gtk-libraries)
-</programlisting>
-        <para>It should now be possible to do things like:</para>
-        <programlisting>
-(#_gtk_widget_destroy w)
-</programlisting>
-      </sect2>
-
-      <sect2 id=3D"UNUSE-INTERFACE-DIR">
-        <para>UNUSE-INTERFACE-DIR</para>
-        <informalfigure>unuse-interface-dir</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>UNUSE-INTERFACE-DIR &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    unuse-interface-dir dir-id
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>dir-id
-            <variablelist>A keyword whose pname, mapped to lower case, nam=
es asubdirectory of "ccl:headers;" (or"ccl:darwin-headers;")</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Tells OpenMCL to remove the interface directory denoted by
-dir-id from the list of interface directories which are
-consulted for
-foreign type and function information. Returns T if the directory
-was on the search list, NIL otherwise.</para>
-      </sect2>
-
-      <sect2 id=3D"TERMINATE-WHEN-UNREACHABLE">
-        <para>TERMINATE-WHEN-UNREACHABLE</para>
-        <informalfigure>terminate-when-unreachable</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>TERMINATE-WHEN-UNREACHABLE &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    terminate-when-unreachable object
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>object
-            <variablelist>A CLOS object of a class for which there existsa=
 method of the generic function<literal>ccl:terminate</literal>.</variablel=
ist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>The "termination" mechanism is a way to have the garbage
-collector run a function right before an object is about to
-become garbage.  It is very similar to the "finalization"
-mechanism which Java has.  It is not standard Common Lisp,
-although other Lisp implementations have similar features.
-It is useful when there is some sort of special cleanup,
-deallocation, or releasing of resources which needs to happen
-when a certain object is no longer being used.</para>
-        <para>When the garbage collector discovers that an object is no
-longer referred to anywhere in the program, it deallocates
-that object, freeing its memory.  However, if
-<literal>ccl:terminate-when-unreachable</literal> has been
-called on the object at any time, the garbage collector first
-invokes the generic function <literal>ccl:terminate</literal>,
-passing it the object as a parameter.</para>
-        <para>Therefore, to make termination do something useful, you need=
 to
-define a method on <literal>ccl:terminate</literal>.</para>
-        <para>Because calling
-<literal>ccl:terminate-when-unreachable</literal> only
-affects a single object, rather than all objects of its
-class, you
-may wish to put a call to it in the
-<literal>initialize-instance</literal> method of a
-class.  Of course, this is only appropriate if you do in fact
-want to use termination for all objects of a given class.</para>
-        <bridgehead renderas=3D"sect3">Example</bridgehead>
-        <programlisting>
+? (external &#34;gtk_main&#34;)
+#&#60;EXTERNAL-ENTRY-POINT &#34;gtk_main&#34; {unresolved} libgtk.so #x304=
6FE46&#62;</programlisting>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>It would be helpful to describe what an soname is and give
+	  examples of one.</para>
+
+	  <para>Does the SHLIB still get returned if the library is
+	  already open?</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_close-shared-library">
+	<indexterm zone=3D"f_close-shared-library">
+	  <primary>close-shared-library</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CLOSE-SHARED-LIBRARY</refname>
+	  <refpurpose>Stops using a shared library, informing the operating
+	  system that it can be unloaded if appropriate.</refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>close-shared-library</function> library &key;
+	  completely</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>library</term>
+
+	      <listitem>
+		<para>either an object of type SHLIB, or a string which
+		designates one by its so-name.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>completely</term>
+
+	      <listitem>
+		<para>a boolean.  The default is T.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>If <varname>completely</varname> is T, sets the
+	  reference count of <varname>library</varname> to 0.  Otherwise,
+	  decrements it by 1.  In either case, if the reference count
+	  becomes 0, <function>close-shared-library</function>
+	  frees all memory resources consumed <varname>library</varname>
+	  and
+	  causes any EXTERNAL-ENTRY-POINTs known to be defined by it to
+	  become unresolved.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_external">
+	<indexterm zone=3D"m_external">
+	  <primary>external</primary>
+	</indexterm>
+	=

+	<refnamediv>
+	  <refname>EXTERNAL</refname>
+	  <refpurpose>Resolves a reference to an external symbol which
+	  is defined in a shared library.</refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>external</function> name =3D> entry
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>name</term>
+	      <listitem>
+		<para>
+		  a simple-string which names an external symbol.
+		  Case-sensitive.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>entry</term>
+	      <listitem>
+		<para>
+		  an object of type EXTERNAL-ENTRY-POINT which maintains
+		  the address of the foreign symbol named by
+		  <varname>name</varname>.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>If there is already an EXTERNAL-ENTRY-POINT for
+	  the symbol named by <varname>name</varname>, finds it and
+	  returns it.  If not, creates one and returns it.</para>
+
+	  <para>Tries to resolve the entry point to a memory address,
+	  and identify the containing library.</para>
+
+	  <para>Be aware that under Darwin, external functions which
+	  are callable from C have underscores prepended to their names,
+	  as in "_fopen".</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_Pff-call">
+	<indexterm zone=3D"f_Pff-call">
+	  <primary>%ff-call</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>%FF-CALL</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>%ff-call</function> entrypoint
+	    {arg-type-keyword arg}* &optional; result-type-keyword
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>entrypoint</term>
+	      =

+	      <listitem>
+		<para>A fixnum or MACPTR</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>arg-type-keyword</term>
+
+	      <listitem>
+		<para>One of the foreign argument-type keywords, described
+		above</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>arg</term>
+
+	      <listitem>
+		<para>A lisp value of type indicated by the corresponding
+		arg-type-keyword</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>result-type-keyword</term>
+
+	      <listitem>
+		<para>One of the foreign argument-type keywords, described
+		above</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Calls the foreign function at address entrypoint passing the
+	  values of each arg as a foreign argument of type indicated by the
+	  corresponding arg-type-keyword. Returns the foreign function
+	  result (coerced to a Lisp object of type indicated by
+	  result-type-keyword), or NIL if result-type-keyword is :VOID or
+	  NIL</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_ff-call">
+	<indexterm zone=3D"m_ff-call">
+	  <primary>ff-call</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>FF-CALL</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>ff-call</function> entrypoint
+	    {arg-type-specifier arg}* &optional; result-type-specifier
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>entrypoint</term>
+
+	      <listitem>
+		<para>A fixnum or MACPTR</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>arg-type-specifer</term>
+
+	      <listitem>
+		<para>One of the foreign argument-type keywords, described
+		above, or an equivalent <link linkend=3D"arb23">foreign
+		type specifier</link>.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>arg</term>
+
+	      <listitem>
+		<para>A lisp value of type indicated by the corresponding
+		arg-type-specifier</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>result-type-specifier</term>
+
+	      <listitem>
+		<para>One of the foreign argument-type keywords, described
+		above, or an equivalent <link linkend=3D"arb23">foreign
+		type specifier</link>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Calls the foreign function at address entrypoint passing the
+	  values of each arg as a foreign argument of type indicated by the
+	  corresponding arg-type-specifier. Returns the foreign function
+	  result (coerced to a Lisp object of type indicated by
+	  result-type-specifier), or NIL if result-type-specifer is :VOID or
+	  NIL</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_Preference-external-entry-point">
+	<indexterm zone=3D"f_Preference-external-entry-point">
+	  <primary>%reference-external-entry-point</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>%REFERENCE-EXTERNAL-ENTRY-POINT</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>%reference-external-entry-point</function> eep
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>eep</term>
+
+	      <listitem>
+		<para>An EXTERNAL-ENTRY-POINT, as obtained by the EXTERNAL
+		macro.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Tries to resolve the address of the EXTERNAL-ENTRY-POINT
+	  eep; returns a fixnum representation of that address if
+	  successful, else signals an error.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_external-call">
+	<indexterm zone=3D"m_external-call">
+	  <primary>external-call</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>EXTERNAL-CALL</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>external-call</function> name
+	    {arg-type-specifier arg}* &optional; result-type-specifier
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>name</term>
+
+	      <listitem>
+		<para>A lisp string. See external, above.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>arg-type-specifer</term>
+
+	      <listitem>
+		<para>One of the foreign argument-type keywords, described
+		above, or an equivalent <link linkend=3D"arb23">foreign
+		type specifier</link>.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>arg</term>
+
+	      <listitem>
+		<para>A lisp value of type indicated by the corresponding
+		arg-type-specifier</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>result-type-specifier</term>
+
+	      <listitem>
+		<para>One of the foreign argument-type keywords, described
+		above, or an equivalent <link linkend=3D"arb23">foreign
+		type specifier</link>.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Calls the foreign function at the address obtained by
+	  resolving the external-entry-point associated with name, passing
+	  the values of each arg as a foreign argument of type indicated by
+	  the corresponding arg-type-specifier. Returns the foreign function
+	  result (coerced to a Lisp object of type indicated by
+	  result-type-specifier), or NIL if result-type-specifer is :VOID or
+	  NIL</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_foreign-symbol-entry">
+	<indexterm zone=3D"f_foreign-symbol-entry">
+	  <primary>foreign-symbol-entry</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>FOREIGN-SYMBOL-ENTRY</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>foreign-symbol-entry</function> name
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>name</term>
+
+	      <listitem>
+		<para>A lisp string.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Tries to resolve the address of the foreign symbol name. If
+	  successful, returns a fixnum representation of that address, else
+	  returns NIL.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_foreign-symbol-address">
+	<indexterm zone=3D"f_foreign-symbol-address">
+	  <primary>foreign-symbol-address</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>FOREIGN-SYMBOL-ADDRESS</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>foreign-symbol-address</function> name
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>name</term>
+
+	      <listitem>
+		<para>A lisp string.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Tries to resolve the address of the foreign symbol
+	  name. If successful, returns that address encapsulated in
+	  <link
+	  linkend=3D"Referencing-and-Using-Foreign-Memory-Addresses">a
+	  MACPTR</link>, else returns NIL.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_defcallback">
+	<indexterm zone=3D"m_defcallback">
+	  <primary>defcallback</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>DEFCALLBACK</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>defcallback</function> name
+	    ({arg-type-specifier var}* &optional; result-type-specifier)
+	    &body; body
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>name</term>
+
+	      <listitem>
+		<para>A symbol which can be made into a special variable</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>arg-type-specifer</term>
+
+	      <listitem>
+		<para>One of the foreign argument-type keywords, described
+		above, or an equivalent <link linkend=3D"arb23">foreign
+		type specifier</link>.
+		In addition, if the keyword
+		:WITHOUT-INTERRUPTS is specified, the callback will be
+		executed with lisp interrupts disabled if the corresponding
+		var is non-NIL. If :WITHOUT-INTERRUPTS is specified more
+		than once, the rightmost instance wins.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>var</term>
+
+	      <listitem>
+		<para>A symbol (lisp variable), which will be bound to a
+		value of the specified type.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>body</term>
+
+	      <listitem>
+		<para>A sequence of lisp forms, which should return a value
+		which can be coerced to the specified result-type.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Proclaims <varname>name</varname>
+	  to be a special variable; sets its value to a
+	  MACPTR which, when called by foreign code, calls a lisp function
+	  which expects foreign arguments of the specified types and which
+	  returns a foreign value of the specified result type. Any argument
+	  variables which correspond to foreign arguments of type :ADDRESS
+	  are bound to stack-allocated MACPTRs.</para>
+	  =

+	  <para>If <varname>name</varname>
+	  is already a callback function pointer, its value is
+	  not changed; instead, it&#39;s arranged
+	  that an
+	  updated version of the lisp callback function will be called.
+	  This feature allows for callback functions to be redefined
+	  incrementally, just like Lisp functions are.</para>
+
+	  <para><function>defcallback</function>
+	  returns the callback pointer, e.g., the
+	  value of <varname>name</varname>.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"rm_sharpsign-underscore">
+	<indexterm zone=3D"rm_sharpsign-underscore">
+	  <primary>#_</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>#_</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Reader Macro</refclass>
+	</refnamediv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Reads a symbol from the current input stream, with *PACKAGE*
+	  bound to the &#34;OS&#34; package and with readtable-case preserved.</p=
ara>
+	  =

+	  <para>Does a lookup on that symbol
+	  in <link linkend=3D"arb25">the OpenMCL interface database</link>,
+	  signalling
+	  an error if no foreign function information can be found for the
+	  symbol in any =

+	  active <link linkend=3D"arb29">interface directory</link>.</para>
+
+	  <para>Notes the foreign function information, including the foreign
+	  function&#39;s return type, the number and type of the foreign
+	  function&#39;s required arguments, and an indication of whether or
+	  not the function accepts additional arguments (via e.g., the
+	  &#34;varargs&#34; mechanism in C).</para>
+
+	  <para>Defines a macroexpansion function on the symbol, which expand
+	  macro calls involving the symbol into EXTERNAL-CALL forms where
+	  foreign argument type specifiers for required arguments and the
+	  return value specifer are provided from the information ind the
+	  database.</para>
+
+	  <para>Returns the symbol.</para>
+
+	  <para>The effect of these steps is that it&#39;s possible to call
+	  foreign functions that take fixed numbers of arguments by simply
+	  providing argument values, as in:</para>
+
+	  <programlisting format=3D"linespecific">(#_isatty fd)
+(#_read fd buf n)</programlisting>
+
+	  <para>and to call foreign functions that take variable numbers of
+	  arguments by specifying the types of non-required args, as in:</para>
+
+	  <programlisting format=3D"linespecific">(with-cstrs ((format-string &#3=
4;the answer is: %d&#34;))
+  (#_printf format-string :int answer))</programlisting>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"rm_sharpsign-questionmark">
+	<indexterm zone=3D"rm_sharpsign-questionmark">
+	  <primary>#?</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>#?</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Reader Macro</refclass>
+	</refnamediv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>In OpenMCL 0.14.2 and later, the #? reader macro can be used to
+	  access foreign variables; this functionality depends on the presence of
+	  &#34;vars.cdb&#34; files in the interface database. The current behavior
+	  of the #? reader macro is to:</para>
+
+	  <para>Read a symbol from the current input stream, with *PACKAGE*
+	  bound to the &#34;OS&#34; package and with readtable-case preserved.</p=
ara>
+	  =

+	  <para>Use that symbol&#39;s pname to access the OpenMCL interface
+	  database, signalling an error if no appropriate foreign variable
+	  information can be found with that name in any active interface
+	  directory.</para>
+
+	  <para>Use type information recorded in the database to construct a
+	  form which can be used to access the foreign variable, and return
+	  that form.</para>
+
+	  <para>Please note that the set of foreign variables declared in header =
files
+	  may or may not match the set of foreign variables exported from
+	  libraries (we&#39;re generally talking about C and Unix here ...). When
+	  they do match, the form constructed by the #? reader macro manages the
+	  details of resolving and tracking changes to the foreign variable&#39;s
+	  address.</para>
+
+	  <para>Future extensions (via prefix arguments to the reader macro) may
+	  offer additional behavior; it might be convenient (for instance) to be
+	  able to access the address of a foreign variable without dereferencing
+	  that address.</para>
+
+	  <para>Foreign variables in C code tend to be platform- and
+	  packge-specific (the canonical example - &#34;errno&#34; - is typically
+	  not a variable when threads are involved. )</para>
+
+	  <para>In LinuxPPC, </para>
+
+	  <programlisting>? #?stderr</programlisting>
+
+	  <para>returns a pointer to the stdio error stream (&#34;stderr&#34; is a
+	  macro under OSX/Darwin).</para>
+
+	  <para>On both LinuxPPC and DarwinPPC, </para>
+
+	  <programlisting>? #?sys_errlist</programlisting>
+
+	  <para>returns a pointer to a C array of C error message strings.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_use-interface-dir">
+	<indexterm zone=3D"f_use-interface-dir">
+	  <primary>use-interface-dir</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>USE-INTERFACE-DIR</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>use-interface-dir</function> dir-id
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>dir-id</term>
+
+	      <listitem>
+		<para>A keyword whose pname, mapped to lower case, names a
+		subdirectory of &#34;ccl:headers;&#34; (or
+		"ccl:darwin-headers;")</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Tells OpenMCL to add the interface directory denoted by
+	  dir-id to the list of interface directories which it consults for
+	  foreign type and function information. Arranges that that
+	  directory is searched before any others.</para>
+
+	  <para>Note that <function>use-interface-dir</function>
+	  merely adds an entry
+	  to a search list.
+	  If the named directory doesn&#39;t exist in the file system
+	  or doesn&#39;t
+	  contain a set of database files, a runtime error may occur
+	  when OpenMCL
+	  tries to open some database file in that directory, and it
+	  will try to
+	  open such a database file whenever it needs to find any
+	  foreign type or
+	  function information. <xref linkend=3D"f_unuse-interface-dir"/>
+	  may come in
+	  handy in that case.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Examples</title>
+
+	  <para>One typically wants interface information to be
+	  available at compile-time (or, in many cases, at read-time).
+	  A typical idiom would be:</para>
+
+	  <programlisting format=3D"linespecific">(eval-when (:compile-toplevel :=
execute)
+  (use-interface-dir :GTK))</programlisting>
+
+	  <para>Using the :GTK interface directory makes available
+	  information on
+	  foreign types, functions, and constants.  It's generally
+	  necessary to
+	  load foreign libraries before actually calling the
+	  foreign code, which for GTK can be done like this:</para>
+
+	  <programlisting>(load-gtk-libraries)</programlisting>
+
+	  <para>It should now be possible to do things like:</para>
+
+	  <programlisting>(#_gtk_widget_destroy w)</programlisting>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_unuse-interface-dir">
+	<indexterm zone=3D"f_unuse-interface-dir">
+	  <primary>unuse-interface-dir</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>UNUSE-INTERFACE-DIR</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>unuse-interface-dir</function> dir-id
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>dir-id</term>
+
+	      <listitem>
+		<para>A keyword whose pname, mapped to lower case, names a
+		subdirectory of &#34;ccl:headers;&#34; (or
+		"ccl:darwin-headers;")</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Tells OpenMCL to remove the interface directory denoted by
+	  dir-id from the list of interface directories which are
+	  consulted for
+	  foreign type and function information. Returns T if the directory
+	  was on the search list, NIL otherwise.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_terminate-when-unreachable">
+	<indexterm zone=3D"f_terminate-when-unreachable">
+	  <primary>terminate-when-unreachable</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>TERMINATE-WHEN-UNREACHABLE</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>terminate-when-unreachable</function> object
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>object</term>
+
+	      <listitem>
+		<para>A CLOS object of a class for which there exists
+		a method of the generic function
+		<function>ccl:terminate</function>.
+		</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>
+	    The "termination" mechanism is a way to have the garbage
+	    collector run a function right before an object is about to
+	    become garbage.  It is very similar to the "finalization"
+	    mechanism which Java has.  It is not standard Common Lisp,
+	    although other Lisp implementations have similar features.
+	    It is useful when there is some sort of special cleanup,
+	    deallocation, or releasing of resources which needs to happen
+	    when a certain object is no longer being used.
+	  </para>
+
+	  <para>
+	    When the garbage collector discovers that an object is no
+	    longer referred to anywhere in the program, it deallocates
+	    that object, freeing its memory.  However, if
+	    <function>ccl:terminate-when-unreachable</function> has been
+	    called on the object at any time, the garbage collector first
+	    invokes the generic function <function>ccl:terminate</function>,
+	    passing it the object as a parameter.
+	  </para>
+
+	  <para>
+	    Therefore, to make termination do something useful, you need to
+	    define a method on <function>ccl:terminate</function>.
+	  </para>
+
+	  <para>
+	    Because calling
+	    <function>ccl:terminate-when-unreachable</function> only
+	    affects a single object, rather than all objects of its
+	    class, you
+	    may wish to put a call to it in the
+	    <function>initialize-instance</function> method of a
+	    class.  Of course, this is only appropriate if you do in fact
+	    want to use termination for all objects of a given class.
+	  </para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Example</title>
+
+      <programlisting format=3D"linespecific">
 (defclass resource-wrapper ()
   ((resource :accessor resource)))
 =

@@ -7835,45 +11197,54 @@
 =

 (defmethod ccl:terminate ((x resource-wrapper))
   (when (resource x)
-    (deallocate (resource x))))
-</programlisting>
-        <bridgehead renderas=3D"sect3">See Also</bridgehead>
-        <para role=3D"continues">Tutorial: Allocating Foreign Data on the =
Lisp Heap</para>
-      </sect2>
+    (deallocate (resource x))))</programlisting>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+
+	  <simplelist type=3D"inline">
+	    <member><xref linkend=3D"arb35"/></member>
+	  </simplelist>
+	</refsect1>
+
+      </refentry>
+
     </sect1>
   </chapter>
 =

   <chapter id=3D"The-Objective-C-Bridge">
-    <para>The Objective-C Bridge
-OS X APIs use a language called "Objective C", which is built on C.
-The Objective-C bridge makes it possible to work with ObjC
-objects and classes from Lisp, and to define classes in Lisp which
-can be used by ObjC.</para>
-    <para>The ultimate
-purpose of the ObjC and Cocoa bridges is to make Cocoa as
-easy as possible to use from OpenMCL, in order to support the
-development of GUI applications and IDEs.  The eventual goal,
-which is much closer than it used to be, is complete integration of
-Cocoa into CLOS (whatever that means).</para>
+    <title>The Objective-C Bridge</title>
+
+    <para>OS X APIs use a language called "Objective C", which is
+    built on C.  The Objective-C bridge makes it possible to work with
+    ObjC objects and classes from Lisp, and to define classes in Lisp
+    which can be used by ObjC.</para>
+    <para>The ultimate purpose of the ObjC and Cocoa bridges is to
+    make Cocoa as easy as possible to use from OpenMCL, in order to
+    support the development of GUI applications and IDEs.  The
+    eventual goal, which is much closer than it used to be, is
+    complete integration of Cocoa into CLOS (whatever that
+    means).</para>
     <para>The current release provides Lisp-like syntax and naming
-conventions for the basic ObjC operations, with automatic
-type processing and messages checked for validity at
-compile-time.  It also provides some convenience facilities
-for working with Cocoa.</para>
+    conventions for the basic ObjC operations, with automatic type
+    processing and messages checked for validity at compile-time.  It
+    also provides some convenience facilities for working with
+    Cocoa.</para>
 =

     <sect1 id=3D"Using-Objective-C-Classes">
-      <para>Using Objective-C Classes
-The class of most "standard" CLOS classes is the
-class named STANDARD-CLASS. In the Objective-C object model, each
-class is an instance of a (usually unique) metaclass, which is
-itself an instance of a "base" metaclass (often the
-metaclass of the class named "NSObject".) So, the
-Objective-C class named "NSWindow" and the ObjC class
-"NSArray" are (sole) instances of their distinct
-metaclasses whose names are also "NSWindow" and
-"NSArray", respectively. (In the Objective-C world,
-it's much more common and useful to specialize class behavior
-such as instance allocation.)</para>
+      <title>Using Objective-C Classes</title>
+
+      <para>The class of most "standard" CLOS classes is the class
+      named STANDARD-CLASS. In the Objective-C object model, each
+      class is an instance of a (usually unique) metaclass, which is
+      itself an instance of a "base" metaclass (often the metaclass of
+      the class named "NSObject".) So, the Objective-C class named
+      "NSWindow" and the ObjC class "NSArray" are (sole) instances of
+      their distinct metaclasses whose names are also "NSWindow" and
+      "NSArray", respectively. (In the Objective-C world, it's much
+      more common and useful to specialize class behavior such as
+      instance allocation.)</para>
       <para>When foreign libraries containing Objective-C classes are first
 loaded, the classes they contain are identified. The foreign class
 name, such as "NSWindow", is mapped to an external symbol in the
@@ -7913,23 +11284,23 @@
     </sect1>
 =

     <sect1 id=3D"Instantiating-Objective-C-Objects">
-      <para>Instantiating Objective-C Objects
-Making an instance of an ObjC class (whether the class in question
-is predefined or defined by the application) involves calling
-MAKE-INSTANCE with the class and a set of initargs as arguments.
-As with STANDARD-CLASS, making an instance involves initializing
-(with INITIALIZE-INSTANCE) an object allocated with
-ALLOCATE-INSTANCE.</para>
+      <title>Instantiating Objective-C Objects</title>
+      <para>Making an instance of an ObjC class (whether the class in
+      question is predefined or defined by the application) involves
+      calling MAKE-INSTANCE with the class and a set of initargs as
+      arguments.  As with STANDARD-CLASS, making an instance involves
+      initializing (with INITIALIZE-INSTANCE) an object allocated with
+      ALLOCATE-INSTANCE.</para>
       <para>For example, you can create an ns:ns-number like this:</para>
       <programlisting>
 ? (make-instance 'ns:ns-number :init-with-int 42)
-#<NS-CF-NUMBER 42 (#x85962210)>
+#&lt;NS-CF-NUMBER 42 (#x85962210)>
 </programlisting>
       <para>It's worth looking at how this would be done if you were
-writing in Objective C:</para>
+      writing in Objective C:</para>
       <programlisting>
 [[NSNumber alloc] initWithInt: 42]
-</programlisting>
+      </programlisting>
       <para>Allocating an instance of an ObjC class involves sending the
 class an "alloc" message, and then using those initargs that
 <emphasis>don't</emphasis> correspond to slot initags as the
@@ -7940,7 +11311,7 @@
 *N*
 =

 ? (setq *n* (ccl::send *n* :init-with-int 42))
-#<NS-CF-NUMBER 42 (#x16D340)>
+#&lt;NS-CF-NUMBER 42 (#x16D340)>
 </programlisting>
       <para>That setq is important; this is a case where init
 decides to replace the object and return the new one, instead
@@ -7966,7 +11337,7 @@
         (ccl::send *controller*
                    :init-with-window-nib-name #@"DataWindow"
                    :owner *controller*))
-#<NS-WINDOW-CONTROLLER <NSWindowController: 0x1fb520> (#x1FB520)>
+#&lt;NS-WINDOW-CONTROLLER &lt;NSWindowController: 0x1fb520> (#x1FB520)>
 </programlisting>
       <para>This example calls (make-instance) with no initargs.  When you
 do this, the object is only allocated, and not initialized.  It
@@ -7974,20 +11345,20 @@
     </sect1>
 =

     <sect1 id=3D"Calling-Objective-C-Methods">
-      <para>Calling Objective-C Methods
-In Objective-C, methods are called "messages", and there's
-a special syntax to send a message to an object:</para>
+      <title>Calling Objective-C Methods</title>
+      <para>In Objective-C, methods are called "messages", and there's
+      a special syntax to send a message to an object:</para>
       <programlisting>
 [w alphaValue]
 [w setAlphaValue: 0.5]
 [v mouse: p inRect: r]
-</programlisting>
+      </programlisting>
       <para>The first line sends the method "alphaValue" to the object
-<literal>w</literal>, with no parameters.  The second line
-sends the method "setAlphaValue", with the parameter 0.5.
-The third line sends the method "mouse:inRect:" - yes, all
-one long word - with the
-parameters <literal>p</literal> and <literal>r</literal>.</para>
+      <literal>w</literal>, with no parameters.  The second line sends
+      the method "setAlphaValue", with the parameter 0.5.  The third
+      line sends the method "mouse:inRect:" - yes, all one long word -
+      with the parameters <literal>p</literal> and
+      <literal>r</literal>.</para>
       <para>In Lisp, these same three lines are:</para>
       <programlisting>
 (send w 'alpha-value)
@@ -8013,91 +11384,65 @@
 method in your subclass.</para>
 =

       <sect2 id=3D"Type-Coercion-for-ObjC-Method-Calls">
-        <para>Type Coercion for ObjC Method Calls
-OpenMCL's FFI handles many common conversions between Lisp
-and foreign data, such as unboxing floating-point args and
-boxing floating-point results.  The bridge adds a few more
-automatic conversions:</para>
-        <para>NIL is equivalent to (%NULL-PTR) for any message argument th=
at
-requires a pointer.</para>
+	<title>Type Coercion for ObjC Method Calls</title>
+        <para>OpenMCL's FFI handles many common conversions between
+        Lisp and foreign data, such as unboxing floating-point args
+        and boxing floating-point results.  The bridge adds a few more
+        automatic conversions:</para>
+        <para>NIL is equivalent to (%NULL-PTR) for any message
+        argument that requires a pointer.</para>
         <para>T/NIL are equivalent to #$YES/#$NO for any boolean argument.=
</para>
-        <para>A #$YES/#$NO returned by any method that returns BOOL will be
-automatically converted to T/NIL.</para>
-        <para>To make this last conversion work, the bridge has to engage
-in a bit of hackery.  The bridge uses ObjC run-time type
-info.  Unfortunately, BOOL is typed as CHAR by ObjC.  Thus,
-a method that returns CHAR might actually return only BOOL,
-or it might return any CHAR.</para>
-        <para>The bridge currently assumes
-that any method that returns CHAR actually returns BOOL.
-But it provides a facility for defining exceptions to this
-assumption: (DEFINE-RETURNS-BOOLEAN-EXCEPTION "charValue").
-Eventually, the best way to handle issues like this is
-probably to get our method type info directly from the
-header files rather than using ObjC's runtime type system.</para>
-        <para>Note that no automatic conversion is currently performed bet=
ween
-Lisp strings and NSStrings.  However, there is a convenient
-reader macro for creating constant NSStrings:</para>
-        <programlisting>
-(SEND W :SET-TITLE #@"My Window")
-</programlisting>
-        <para>Note that #@"Hello" is a full ObjC object, so
-messages can be sent to it: (SEND #@"Hello" 'LENGTH).</para>
-        <para>To go in the other direction, use the function
-(ccl::lisp-string-from-nsstring).</para>
-        <para>To create variable NSStrings (which you will later
-want to change the
-values of), consider using CCL::NS-LISP-STRING.</para>
+        <para>A #$YES/#$NO returned by any method that returns BOOL
+        will be automatically converted to T/NIL.</para>
       </sect2>
 =

       <sect2 id=3D"Methods-which-Return-Structures">
-        <para>Methods which Return Structures
-Some Cocoa methods return small structures, such as those used
-to represent points, rects, sizes and ranges. When writing in
-Objective C, the compiler hides the implementation details.
-Unfortunately, in Lisp we must be slightly more aware of them.</para>
-        <para>Methods which return structures are called in a special way;
-the caller allocates space for the result, and passes a pointer
-to it as an extra argument to the method.  This is called a
-Structure Return, or STRET.  Don't look at me; I don't name
-these things.</para>
+	<title>Methods which Return Structures</title>
+        <para>Some Cocoa methods return small structures, such as
+        those used to represent points, rects, sizes and ranges. When
+        writing in Objective C, the compiler hides the implementation
+        details.  Unfortunately, in Lisp we must be slightly more
+        aware of them.</para>
+        <para>Methods which return structures are called in a special
+        way; the caller allocates space for the result, and passes a
+        pointer to it as an extra argument to the method.  This is
+        called a Structure Return, or STRET.  Don't look at me; I
+        don't name these things.</para>
         <para>Here's a simple use of this in Objective C.  The first line
-sends the "bounds" message to v1, which returns a rectangle.
-The second line sends the "setBounds" message to v2, passing
-that same rectangle as a parameter.</para>
+	sends the "bounds" message to v1, which returns a rectangle.
+	The second line sends the "setBounds" message to v2, passing
+	that same rectangle as a parameter.</para>
         <programlisting>
 NSRect r =3D [v1 bounds];
 [v2 setBounds r];
-</programlisting>
-        <para>In Lisp, we must explicitly allocate the memory, which is
-done most easily and safely with .
-We do it like this:</para>
+	</programlisting>
+        <para>In Lisp, we must explicitly allocate the memory, which
+        is done most easily and safely with <xref linkend=3D"m_rlet"/>.
+        We do it like this:</para>
         <programlisting>
-(rlet ((r :<NSR>ect))
+(rlet ((r :&lt;NSR>ect))
   (send/stret r v1 'bounds)
   (send v2 :set-bounds r))
 </programlisting>
-        <para>The rlet allocates the storage (but doesn't initialize it),
-and makes sure that it will be deallocated when we're done.
-It binds the variable r to refer to it.
-The call to <literal>send/stret</literal> is just like
-an ordinary call to
-<literal>send</literal>, except that r is passed as an
-extra, first parameter.  The third line, which calls
-<literal>send</literal>, does not need to do anything
-special, because there's nothing complicated about passing
-a structure as a parameter.</para>
-        <para>In order to make STRETs easier to use, the bridge provides t=
wo
-conveniences.</para>
+        <para>The rlet allocates the storage (but doesn't initialize
+        it), and makes sure that it will be deallocated when we're
+        done.  It binds the variable r to refer to it.  The call to
+        <literal>send/stret</literal> is just like an ordinary call to
+        <literal>send</literal>, except that r is passed as an extra,
+        first parameter.  The third line, which calls
+        <literal>send</literal>, does not need to do anything special,
+        because there's nothing complicated about passing a structure
+        as a parameter.</para>
+	<para>In order to make STRETs easier to use, the bridge
+	provides two conveniences.</para>
         <para>First, you can use the macros <literal>slet</literal>
-and <literal>slet*</literal> to allocate and
-initialize local variables to foreign structures in one
-step.  The example above could have been written more tersely
-as:</para>
+        and <literal>slet*</literal> to allocate and initialize local
+        variables to foreign structures in one step.  The example
+        above could have been written more tersely as:</para>
         <programlisting>
 (slet ((r (send v1 'bounds)))
   (send v2 :set-bounds r))
-</programlisting>
+	</programlisting>
         <para>Second, when one call to <literal>send</literal> is made
 inside another, the inner one has an implicit
 <literal>slet</literal> around it.  So, one could in fact
@@ -8134,7 +11479,8 @@
       </sect2>
 =

       <sect2 id=3D"Variable-Arity-Messages">
-        <para>Variable-Arity Messages
+	<title>Variable-Arity Messages</title>
+        <para>
 There are a few messages in Cocoa which take variable numbers
 of arguments. Perhaps the most common examples involve
 formatted strings:</para>
@@ -8162,116 +11508,116 @@
       </sect2>
 =

       <sect2 id=3D"Optimization">
-        <para>Optimization
-The bridge works fairly hard to optimize message sends, when
-it has enough information to do so.  There are two cases when
-it does.  In either, a message send should be nearly as
-efficient as when writing in Objective C.</para>
-        <para>The first case is when both the message
-and the receiver's class are known at
-compile-time. In general, the only way the receiver's class
-is known is if you declare it, which you can do with
-either a DECLARE or a THE form.  For example:</para>
+	<title>Optimization</title>
+        <para>The bridge works fairly hard to optimize message sends,
+        when it has enough information to do so.  There are two cases
+        when it does.  In either, a message send should be nearly as
+        efficient as when writing in Objective C.</para>
+        <para>The first case is when both the message and the
+        receiver's class are known at compile-time. In general, the
+        only way the receiver's class is known is if you declare it,
+        which you can do with either a DECLARE or a THE form.  For
+        example:</para>
         <programlisting>
 (send (the ns:ns-window w) 'center)
-</programlisting>
+	</programlisting>
         <para>Note that there is no way in ObjC to name the class of a
-class.  Thus the bridge provides a declaration, @METACLASS.
-The
-type of an instance of "NSColor" is ns:ns-color.  The type of
-the <emphasis>class</emphasis>
-"NSColor" is (@metaclass ns:ns-color):</para>
+        class.  Thus the bridge provides a declaration, @METACLASS.
+        The type of an instance of "NSColor" is ns:ns-color.  The type
+        of the <emphasis>class</emphasis> "NSColor" is (@metaclass
+        ns:ns-color):</para>
         <programlisting>
 (let ((c (find-class 'ns:ns-color)))
   (declare ((ccl::@metaclass ns:ns-color) c))
   (send c 'white-color))
 </programlisting>
-        <para>The other case that alllows optimization is when only the
-message is known at compile-time, but its type signature
-is unique. Of the more-than-6000 messages currently provided by
-Cocoa, only about 50 of them have nonunique type signatures.</para>
-        <para>An example of a message with a type signature that is not
-unique is SET.  It returns VOID for NSColor, but ID for NSSet.
-In order to optimize sends of messages with nonunique type
-signatures, the class of the receiver must be declared at
-compile-time.</para>
-        <para>If the type signature is nonunique or the message is unknown
-at compile-time, then a slower runtime call must be used.</para>
-        <para>When the receiver's class is unknown, the bridge's ability to
-optimize relies on a type-signature table which it maintains.
-When first loaded, the bridge initializes this table
-by scanning every method of every ObjC class.  When new methods
-are defined later, the table must be updated.  This happens
-automatically when you define methods in Lisp.  After any
-other major change, such as loading an external framework,
-you should rebuild the table:</para>
+        <para>The other case that alllows optimization is when only
+        the message is known at compile-time, but its type signature
+        is unique. Of the more-than-6000 messages currently provided
+        by Cocoa, only about 50 of them have nonunique type
+        signatures.</para>
+        <para>An example of a message with a type signature that is
+        not unique is SET.  It returns VOID for NSColor, but ID for
+        NSSet.  In order to optimize sends of messages with nonunique
+        type signatures, the class of the receiver must be declared at
+        compile-time.</para>
+        <para>If the type signature is nonunique or the message is
+        unknown at compile-time, then a slower runtime call must be
+        used.</para>
+        <para>When the receiver's class is unknown, the bridge's
+        ability to optimize relies on a type-signature table which it
+        maintains.  When first loaded, the bridge initializes this
+        table by scanning every method of every ObjC class.  When new
+        methods are defined later, the table must be updated.  This
+        happens automatically when you define methods in Lisp.  After
+        any other major change, such as loading an external framework,
+        you should rebuild the table:</para>
         <programlisting>
 ? (update-type-signatures)
 </programlisting>
         <para>Because <literal>send</literal> and its relatives
-<literal>send-super</literal>,
-<literal>send/stret</literal>, and
-<literal>send-super/stret</literal> are macros, they cannot
-be <literal>funcall</literal>ed, <literal>apply</literal>ed,
-or passed as arguments to functions.</para>
-        <para>To work around this,
-there are function equivalents to them:
-<literal>%send</literal>,
-<literal>%send-super</literal>,
-<literal>%send/stret</literal>, and
-<literal>%send-super/stret</literal>.  However, these
-functions should be used only when the macros will not do,
-because they are unable to optimize.</para>
+        <literal>send-super</literal>, <literal>send/stret</literal>,
+        and <literal>send-super/stret</literal> are macros, they
+        cannot be <literal>funcall</literal>ed,
+        <literal>apply</literal>ed, or passed as arguments to
+        functions.</para>
+        <para>To work around this, there are function equivalents to
+        them: <literal>%send</literal>,
+        <literal>%send-super</literal>,
+        <literal>%send/stret</literal>, and
+        <literal>%send-super/stret</literal>.  However, these
+        functions should be used only when the macros will not do,
+        because they are unable to optimize.</para>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"Defining-Objective-C-Classes">
-      <para>Defining Objective-C Classes
-You can define your own foreign classes, which can then be
-passed to foreign functions; the methods which you implement
-in Lisp will be made available to the foreign code as
-callbacks.</para>
-      <para>You can also define subclasses of existing classes, implementi=
ng
-your subclass in Lisp even though the parent class was in
-Objective C.  One such subclass is
-CCL::NS-LISP-STRING.
-It is also particularly useful to make subclasses of
-NS-WINDOW-CONTROLLER.</para>
-      <para>We can use the MOP to define new Objective-C classes,
-but we have to do something a little
-funny: the :METACLASS that we'd want to use in a DEFCLASS option
-generally doesn't exist until we've created the class (recall
-that ObjC classes have, for the sake of argument, unique and private
-metaclasses.) We can sort of sleaze our way around this by specifying
-a known ObjC metaclass object name as the value of
-the DEFCLASS :METACLASS object; the metaclass of the root class
-NS:NS-OBJECT, NS:+NS-OBJECT, makes a good choice. To make a subclass
-of NS:NS-WINDOW (that, for simplicity's sake, doesn't define any
-new slots), we could do:</para>
+      <title>Defining Objective-C Classes</title>
+      <para>You can define your own foreign classes, which can then be
+      passed to foreign functions; the methods which you implement in
+      Lisp will be made available to the foreign code as
+      callbacks.</para>
+      <para>You can also define subclasses of existing classes,
+      implementing your subclass in Lisp even though the parent class
+      was in Objective C.  One such subclass is CCL::NS-LISP-STRING.
+      It is also particularly useful to make subclasses of
+      NS-WINDOW-CONTROLLER.</para>
+      <para>We can use the MOP to define new Objective-C classes, but
+      we have to do something a little funny: the :METACLASS that we'd
+      want to use in a DEFCLASS option generally doesn't exist until
+      we've created the class (recall that ObjC classes have, for the
+      sake of argument, unique and private metaclasses.) We can sort
+      of sleaze our way around this by specifying a known ObjC
+      metaclass object name as the value of the DEFCLASS :METACLASS
+      object; the metaclass of the root class NS:NS-OBJECT,
+      NS:+NS-OBJECT, makes a good choice. To make a subclass of
+      NS:NS-WINDOW (that, for simplicity's sake, doesn't define any
+      new slots), we could do:</para>
       <programlisting>
 (defclass example-window (ns:ns-window)
   ()
   (:metaclass ns:+ns-object))
 </programlisting>
       <para>That'll create a new ObjC class named EXAMPLE-WINDOW whose
-metaclass is the class named +EXAMPLE-WINDOW. The class will be an
-object of type OBJC:OBJC-CLASS, and the metaclass will be of type
-OBJC:OBJC-METACLASS.  EXAMPLE-WINDOW will be a subclass of
-NS-WINDOW.</para>
+      metaclass is the class named +EXAMPLE-WINDOW. The class will be
+      an object of type OBJC:OBJC-CLASS, and the metaclass will be of
+      type OBJC:OBJC-METACLASS.  EXAMPLE-WINDOW will be a subclass of
+      NS-WINDOW.</para>
 =

       <sect2 id=3D"Defining-classes-with-foreign-slots">
-        <para>Defining classes with foreign slots
-If a slot specification in an Objective-C class definition
-contains the keyword :FOREIGN-TYPE, the slot will be a "foreign
-slot" (i.e. an ObjC instance variable). Be aware that it is an
-error to redefine an ObjC class so that its foreign slots
-change in any way, and OpenMCL doesn't do anything consistent
-when you try to.</para>
-        <para>The value of the :FOREIGN-TYPE initarg should be a foreign t=
ype
-specifier. For example, if we wanted (for some reason) to define a
-subclass of NS:NS-WINDOW that kept track of the number of key events
-it had received (and needed an instance variable to keep that
-information in), we could say:</para>
+	<title>Defining classes with foreign slots</title>
+        <para>If a slot specification in an Objective-C class
+        definition contains the keyword :FOREIGN-TYPE, the slot will
+        be a "foreign slot" (i.e. an ObjC instance variable). Be aware
+        that it is an error to redefine an ObjC class so that its
+        foreign slots change in any way, and OpenMCL doesn't do
+        anything consistent when you try to.</para>
+        <para>The value of the :FOREIGN-TYPE initarg should be a
+        foreign type specifier. For example, if we wanted (for some
+        reason) to define a subclass of NS:NS-WINDOW that kept track
+        of the number of key events it had received (and needed an
+        instance variable to keep that information in), we could
+        say:</para>
         <programlisting>
 (defclass key-event-counting-window (ns:ns-window)
   ((key-event-count :foreign-type :int
@@ -8280,49 +11626,49 @@
   (:metaclass ns:+ns-object))
 </programlisting>
         <para>Foreign slots are always SLOT-BOUNDP, and the initform
-above is redundant: foreign slots are initialized to binary 0.</para>
+        above is redundant: foreign slots are initialized to binary
+        0.</para>
       </sect2>
 =

       <sect2 id=3D"Defining-classes-with-Lisp-slots">
-        <para>Defining classes with Lisp slots
-A slot specification in an ObjC class definition that doesn't
-contain the :FOREIGN-TYPE initarg defines a pretty-much normal lisp
-slot that'll happen to be associated with "an instance of a
-foreign class". For instance:</para>
+	<title>Defining classes with Lisp slots</title>
+        <para>A slot specification in an ObjC class definition that
+        doesn't contain the :FOREIGN-TYPE initarg defines a
+        pretty-much normal lisp slot that'll happen to be associated
+        with "an instance of a foreign class". For instance:</para>
         <programlisting>
 (defclass hemlock-buffer-string (ns:ns-string)
   ((hemlock-buffer :type hi::hemlock-buffer
                    :initform hi::%make-hemlock-buffer
                    :accessor string-hemlock-buffer))
   (:metaclass ns:+ns-object))
-</programlisting>
+	</programlisting>
         <para>As one might expect, this has memory-management
-implications: we
-have to maintain an association between a MACPTR and a set of lisp
-objects (its slots) as long as the ObjC instance exists, and we have
-to ensure that the ObjC instance exists (does not have its -dealloc
-method called) while lisp is trying to think of it as a first-class
-object that can't be "deallocated" while it's still
-possible to reference it. Associating one or more lisp objects with a
-foreign instance is something that's often very useful; if you
-were to do this "by hand", you'd have to face many of the
-same memory-management issues.</para>
+        implications: we have to maintain an association between a
+        MACPTR and a set of lisp objects (its slots) as long as the
+        ObjC instance exists, and we have to ensure that the ObjC
+        instance exists (does not have its -dealloc method called)
+        while lisp is trying to think of it as a first-class object
+        that can't be "deallocated" while it's still possible to
+        reference it. Associating one or more lisp objects with a
+        foreign instance is something that's often very useful; if you
+        were to do this "by hand", you'd have to face many of the same
+        memory-management issues.</para>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"Defining-Objective-C-Methods">
-      <para>Defining Objective-C Methods
-In ObjC, unlike in CLOS, every method belongs to some
-particular class.  This is probably not a strange
-concept to you, because C++ and Java do the same thing.
-When you use Lisp to define ObjC methods, it is only
-possible to define methods belonging to ObjC classes which
-have been defined in Lisp.</para>
+      <title>Defining Objective-C Methods</title>
+      <para>In ObjC, unlike in CLOS, every method belongs to some
+      particular class.  This is probably not a strange concept to
+      you, because C++ and Java do the same thing.  When you use Lisp
+      to define ObjC methods, it is only possible to define methods
+      belonging to ObjC classes which have been defined in
+      Lisp.</para>
       <para>The macro <literal>define-objc-method</literal> is used
-for this.  As described in , the names
-of ObjC methods are broken into pieces, each piece followed
-by a parameter.  The types of all parameters must be explicitly
-declared.</para>
+      for this.  As described in , the names of ObjC methods are
+      broken into pieces, each piece followed by a parameter.  The
+      types of all parameters must be explicitly declared.</para>
       <para>Right now, I'm not sure how to formally describe the usage
 of define-objc-method, so I'm going to do it with some short
 examples.  Let us define a class to use in them:</para>
@@ -8332,32 +11678,29 @@
    (data :initform nil :accessor data))
   (:metaclass ns:+ns-object))
 </programlisting>
-      <para>There's nothing special about this class.
-It inherits from ns:ns-window-controller.
-It has two slots: <literal>window</literal> is a
-foreign slot, stored in the ObjC world; and
-<literal>data</literal> is an ordinary slot, stored in
-the Lisp world.</para>
+      <para>There's nothing special about this class.  It inherits
+      from ns:ns-window-controller.  It has two slots:
+      <literal>window</literal> is a foreign slot, stored in the ObjC
+      world; and <literal>data</literal> is an ordinary slot, stored
+      in the Lisp world.</para>
       <para>Here is an example of how to define a method which takes
-no arguments.  It happens to be an initialization method,
-but that's not important:</para>
+      no arguments.  It happens to be an initialization method, but
+      that's not important:</para>
       <programlisting>
  (define-objc-method ((:id get-window)
                      data-window-controller)
   (window self))
-</programlisting>
-      <para>The return type of this method is the foreign type :id, which
-is used for all ObjC objects.
-The name of the method is
-<literal>get-window</literal>.  The body of the method is
-the single line (window self).  The variable
-<literal>self</literal> is bound, within the body, to the
-instance which is receiving the message.  The call to
-<literal>window</literal>
-uses the CLOS accessor to get the value of the window field.</para>
+      </programlisting>
+      <para>The return type of this method is the foreign type :id,
+      which is used for all ObjC objects.  The name of the method is
+      <literal>get-window</literal>.  The body of the method is the
+      single line (window self).  The variable <literal>self</literal>
+      is bound, within the body, to the instance which is receiving
+      the message.  The call to <literal>window</literal> uses the
+      CLOS accessor to get the value of the window field.</para>
       <para>Here's an example which takes a parameter.  Notice that
-the name of the method without a parameter was an ordinary
-symbol, but with a parameter, it's a keyword:</para>
+      the name of the method without a parameter was an ordinary
+      symbol, but with a parameter, it's a keyword:</para>
       <programlisting>
 (define-objc-method ((:id :init-with-multiplier (:int multiplier))
                      data-window-controller)
@@ -8366,14 +11709,13 @@
     (setf (aref (data self) i)
           (* i multiplier)))
   self)
-</programlisting>
+      </programlisting>
       <para>To Objective-C code which uses the class, the name of this
-method is "initWithMultiplier:".  The name of the parameter
-is <literal>multiplier</literal>, and its type is :int.
-The body of the method
-does some meaningless things.  Then it returns
-<literal>self</literal>, because
-this is an initialization method.</para>
+      method is "initWithMultiplier:".  The name of the parameter is
+      <literal>multiplier</literal>, and its type is :int.  The body
+      of the method does some meaningless things.  Then it returns
+      <literal>self</literal>, because this is an initialization
+      method.</para>
       <para>Here's an example with more than one parameter:</para>
       <programlisting>
 (define-objc-method ((:id :init-with-multiplier (:int multiplier)
@@ -8385,15 +11727,15 @@
           (+ (* i multiplier)
              addend)))
   self)
-</programlisting>
+      </programlisting>
       <para>To Objective-C, the name of this method is
-"initWithMultiplier:andAddend:".  Both parameters are
-of type :int; the first is named <literal>multiplier</literal>,
-and the second is <literal>addend</literal>.  Again, the
-method returns <literal>self</literal>.</para>
-      <para>Here is a method which does not return any value, a so-called
-"void method".  Where our other methods said :id, this one says
-:void for the return type:</para>
+      "initWithMultiplier:andAddend:".  Both parameters are of type
+      :int; the first is named <literal>multiplier</literal>, and the
+      second is <literal>addend</literal>.  Again, the method returns
+      <literal>self</literal>.</para>
+      <para>Here is a method which does not return any value, a
+      so-called "void method".  Where our other methods said :id, this
+      one says :void for the return type:</para>
       <programlisting>
 (define-objc-method ((:void :take-action (:id sender))
                      data-window-controller)
@@ -8402,106 +11744,88 @@
     (setf (aref (data self) i)
           (- (aref (data self) i)))))
 </programlisting>
-      <para>This method would be called "takeAction:" in ObjC.
-The convention for methods that are going to be used as Cocoa
-actions is that they take one parameter, which is the object
-responsible for triggering the action.  However, this method
-doesn't actually need to use that parameter, so it explicitly
-ignores it to avoid a compiler warning.  As promised, the
-method doesn't return any value.</para>
-      <para>There is also an alternate syntax, illustrated here.  The foll=
owing two method definitions are equivalent:</para>
+      <para>This method would be called "takeAction:" in ObjC.  The
+      convention for methods that are going to be used as Cocoa
+      actions is that they take one parameter, which is the object
+      responsible for triggering the action.  However, this method
+      doesn't actually need to use that parameter, so it explicitly
+      ignores it to avoid a compiler warning.  As promised, the method
+      doesn't return any value.</para>
+      <para>There is also an alternate syntax, illustrated here.  The
+      following two method definitions are equivalent:</para>
       <programlisting>
 (define-objc-method ("applicationShouldTerminate:"
                      "LispApplicationDelegate")
-                    (:id sender :<BOOL>)
+                    (:id sender :&lt;BOOL>)
   (declare (ignore sender))
   nil)
 =

-(define-objc-method ((:<BOOL>
+(define-objc-method ((:&lt;BOOL>
                       :application-should-terminate sender)
                      lisp-application-delegate)
   (declare (ignore sender))
   nil)
 </programlisting>
       <sect2 id=3D"Method-Redefinition-Constraints">
-        <para>Method Redefinition Constraints
-Objective C was not designed, as Lisp was, with runtime
-redefinition in mind.  So, there are a few constraints about
-how and when you can replace the definition of an Objective C
-method.  Currently, if you break these rules, nothing will
-collapse, but the behaviour will be confusing; so don't.</para>
-        <para>Objective C methods can be redefined at runtime, but their
-signatures shouldn't change.  That is, the types of the arguments
-and the return type have to stay the same.  The reason for this
-is that changing the signature changes the selector which is used
-to call the method.</para>
-        <para>When a method has already been defined in one class, and you
-define it in a subclass, shadowing the original method, they
-must both have the same type signature.  There is no such
-constraint, though, if the two classes aren't related and the
-methods just happen to have the same name.</para>
+	<title>Method Redefinition Constraints</title>
+        <para>Objective C was not designed, as Lisp was, with runtime
+        redefinition in mind.  So, there are a few constraints about
+        how and when you can replace the definition of an Objective C
+        method.  Currently, if you break these rules, nothing will
+        collapse, but the behaviour will be confusing; so
+        don't.</para>
+        <para>Objective C methods can be redefined at runtime, but
+        their signatures shouldn't change.  That is, the types of the
+        arguments and the return type have to stay the same.  The
+        reason for this is that changing the signature changes the
+        selector which is used to call the method.</para>
+        <para>When a method has already been defined in one class, and
+        you define it in a subclass, shadowing the original method,
+        they must both have the same type signature.  There is no such
+        constraint, though, if the two classes aren't related and the
+        methods just happen to have the same name.</para>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"How-Objective-C-Names-are-Mapped-to-Lisp-Symbols">
-      <para>How Objective-C Names are Mapped to Lisp Symbols
-There is a standard set of naming conventions for Cocoa classes,
-messages, etc.  As long as they are followed, the bridge is fairly
-good at automaticallly translating between ObjC and Lisp names.</para>
+      <title>How Objective-C Names are Mapped to Lisp Symbols</title>
+      <para>There is a standard set of naming conventions for Cocoa
+      classes, messages, etc.  As long as they are followed, the
+      bridge is fairly good at automaticallly translating between ObjC
+      and Lisp names.</para>
       <para>For example, "NSOpenGLView" becomes ns:ns-opengl-view;
-"NSURLHandleClient" becomes ns:ns-url-handle-client; and
-"nextEventMatchingMask:untilDate:inMode:dequeue:" becomes
-(:next-event-matching-mask :until-date :in-mode :dequeue).
-What a mouthful.</para>
-      <para>To see how a given ObjC or Lisp name will be translated by the
-bridge, you can use the following functions:</para>
-      <colspec>
-        <thead cols=3D"1">
-          <tbody colwidth=3D"100*"></tbody>
-          <row>
-            <abstract>
-              <entry>(ccl::objc-to-lisp-classname string)</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>(ccl::lisp-to-objc-classname symbol)</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>(ccl::objc-to-lisp-message string)</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>(ccl::lisp-to-objc-message string)</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>(ccl::objc-to-lisp-init string)</entry>
-            =

-            </abstract>
-            <abstract>
-              <entry>(ccl::lisp-to-objc-init keyword-list)</entry>
-            =

-            </abstract>
-          </row>
-        </thead>
-      </colspec>
-      <para>Of course, there will always be exceptions to any naming conve=
ntion.
-Please tell us on the mailing lists if you come across any
-name translation problems
-that seem to be bugs.  Otherwise, the bridge provides two ways of
-dealing with exceptions:</para>
+      "NSURLHandleClient" becomes ns:ns-url-handle-client; and
+      "nextEventMatchingMask:untilDate:inMode:dequeue:" becomes
+      (:next-event-matching-mask :until-date :in-mode :dequeue).  What
+      a mouthful.</para>
+      <para>To see how a given ObjC or Lisp name will be translated by
+      the bridge, you can use the following functions:</para>
+	<simplelist type=3D"vert">
+	  <member>(ccl::objc-to-lisp-classname string)</member>
+	  <member>(ccl::lisp-to-objc-classname symbol)</member>
+	  <member>(ccl::objc-to-lisp-message string)</member>
+	  <member>(ccl::lisp-to-objc-message string)</member>
+	  <member>(ccl::objc-to-lisp-init string)</member>
+	  <member>(ccl::lisp-to-objc-init keyword-list)</member>
+	</simplelist>
+
+      <para>Of course, there will always be exceptions to any naming
+      convention.  Please tell us on the mailing lists if you come
+      across any name translation problems that seem to be bugs.
+      Otherwise, the bridge provides two ways of dealing with
+      exceptions:</para>
       <para>First, you can pass a string as the class name of
-MAKE-OBJC-INSTANCE and as the message to SEND.  These strings will
-be directly interpreted as ObjC names, with no translation. This
-is useful for a one-time exception.  For example:</para>
+      MAKE-OBJC-INSTANCE and as the message to SEND.  These strings
+      will be directly interpreted as ObjC names, with no
+      translation. This is useful for a one-time exception.  For
+      example:</para>
       <programlisting>
 (ccl::make-objc-instance "WiErDclass")
 (ccl::send o "WiErDmEsSaGe:WithARG:" x y)
-</programlisting>
-      <para>Alternatively, you can define a special translation rule for y=
our
-exception.  This is useful for an exceptional name that you need
-to use througout your code.  Some examples:</para>
+      </programlisting>
+      <para>Alternatively, you can define a special translation rule
+      for your exception.  This is useful for an exceptional name that
+      you need to use througout your code.  Some examples:</para>
       <programlisting>
 (ccl::define-classname-translation "WiErDclass" wierd-class)
 (ccl::define-message-translation "WiErDmEsSaGe:WithARG:" (:weird-message :=
with-arg))
@@ -8517,288 +11841,275 @@
       <programlisting>
 (ccl::define-special-objc-word "QuickDraw")
 </programlisting>
-      <para>Note that message keywords in a SEND such as
-(SEND V :MOUSE P :IN-RECT R) may
-look like the keyword arguments in a Lisp function call, but they
-really aren't. All keywords must be
-present and the order is significant. Neither (:IN-RECT :MOUSE) nor
-(:MOUSE) translate to "mouse:inRect:"</para>
-      <para>Also, as a special exception, an "init" prefix is optional in =
the
-initializer keywords, so
-(MAKE-OBJC-INSTANCE 'NS-NUMBER :INIT-WITH-FLOAT 2.7) can also
-be expressed as
-(MAKE-OBJC-INSTANCE 'NS-NUMBER :WITH-FLOAT 2.7)</para>
+      <para>Note that message keywords in a SEND such as (SEND V
+      :MOUSE P :IN-RECT R) may look like the keyword arguments in a
+      Lisp function call, but they really aren't. All keywords must be
+      present and the order is significant. Neither (:IN-RECT :MOUSE)
+      nor (:MOUSE) translate to "mouse:inRect:"</para>
+      <para>Also, as a special exception, an "init" prefix is optional
+      in the initializer keywords, so (MAKE-OBJC-INSTANCE 'NS-NUMBER
+      :INIT-WITH-FLOAT 2.7) can also be expressed as
+      (MAKE-OBJC-INSTANCE 'NS-NUMBER :WITH-FLOAT 2.7)</para>
     </sect1>
   </chapter>
 =

-  <chapter id=3D"Using-OpenMCL-with-Mac-OS-X--the-Darwin-Kernel--and-the-C=
ocoa-GUI-API">
-    <para>Using OpenMCL with Mac OS X, the Darwin Kernel,  and the Cocoa G=
UI API</para>
-
-    <sect1 id=3D"Differences-in-OpenMCL-between-Darwin-and-MacOS-X">
-      <para>Differences in OpenMCL between Darwin and MacOS X
-Most of the documentation and whatever experience you may have in using Op=
enMCL under LinuxPPC should apply to using it under Darwin/MacOS X. There a=
re some differences between the platforms, and these differences are someti=
mes exposed in the implementation.</para>
-
-      <sect2 id=3D"FASL-file-segregation-">
-        <para>FASL file segregation.
-99% of the compiled lisp code in the two implementations is
-identical. Since both implementations target the PowerPC, this
-shouldn't be too surprising.</para>
-        <para>The other 1% - code which deals with foreign functions or da=
ta or
-which deals directly with the operating system - is very different but
-superficially similar. The effects of running such code compiled for
-the wrong platform range from harmless to catastrophic.</para>
-        <para>During bootstrapping, the 1% proved troublesome enough that =
it seemed
-wise to strictly separate the two implementations.</para>
-        <para>FASL files have different file types (.dfsl for Darwin, .pfs=
l for
-LinuxPPC) and contain different identifying information; it's not
-possible to successfully load FASL files compiled for one
-implementation into the other.</para>
-        <para>I think that it's wise to maintain this distinction; I spent=
 a lot
-less time recompiling the 99% of "non-troublesome" code than I'd been
-spending tracking down bugs caused by the other 1%.</para>
-      </sect2>
+  <chapter id=3D"Platform-specific-notes">
+    <title>Platform-specific notes</title>
+      =

+
+    <sect1 id=3D"Platform-specific-overview">
+      <title>Overview</title>
+      <para> The documentation and whatever experience you may have in
+      using OpenMCL under Linux should also apply to using it under
+      Darwin/MacOS X and FreeBSD. There are some differences between
+      the platforms, and these differences are sometimes exposed in
+      the implementation.</para>
+
 =

       <sect2 id=3D"File-system-case">
-        <para>File-system case
-Darwin and MacOS X use HFS+ file systems by default; HFS+ file systems
-are case-insensitive. Most of OpenMCL's filesystem and pathname code
-assumes that the underlying filesystem is case-sensitive; this
-assumption extends to functions like EQUAL, which assumes that #p"FIXTHIS"
-and #p"foo" denote different, un-EQUAL filenames. Since Darwin/MacOS X
-can also use UFS and NFS filesystems, the opposite assumption would be
-no more correct than the one that's currently made.</para>
+	<title>File-system case</title>
+
+	<para>Darwin and MacOS X use HFS+ file systems by default;
+	HFS+ file systems are usually case-insensitive. Most of
+	OpenMCL's filesystem and pathname code assumes that the
+	underlying filesystem is case-sensitive; this assumption
+	extends to functions like EQUAL, which assumes that #p"FOO"
+	and #p"foo" denote different, un-EQUAL filenames. Since
+	Darwin/MacOS X can also use UFS and NFS filesystems, the
+	opposite assumption would be no more correct than the one
+	that's currently made.</para>
         <para>Whatever the best solution to this problem turns out to be, =
there are
 some practical considerations. Doing:</para>
         <programlisting>
 ? (save-application "DPPCCL")
-</programlisting>
-        <para>has the unfortunate side-effect of trying to overwrite the D=
arwin
-OpenMCL kernel, "dppccl", on a case-insensitive filesystem.</para>
-        <para>To work around this, the Darwin OpenMCL kernel expects the d=
efault
-heap image file name to be the kernel's own filename with the string
-".image" appended, so the idiom would be:</para>
-        <programlisting>? (save-application "dppccl.image")
-</programlisting>
+	</programlisting>
+        <para>on 32-bit DarwinPPC has the unfortunate side-effect of
+        trying to overwrite the Darwin OpenMCL kernel, "dppccl", on a
+        case-insensitive filesystem.</para>
+        <para>To work around this, the Darwin OpenMCL kernel expects
+        the default heap image file name to be the kernel's own
+        filename with the string ".image" appended, so the idiom would
+        be:</para>
+        <programlisting>
+? (save-application "dppccl.image")
+	</programlisting>
       </sect2>
 =

       <sect2 id=3D"Line-Termination-Characters">
-        <para>Line Termination Characters
-MacOSX effectively supports two distinct line-termination
-conventions. Programs in its Darwin substrate follow the Unix
-convention of recognizing #\LineFeed as a line terminator; traditional
-MacOS programs use #\Return for this purpose.</para>
-        <para>OpenMCL follows the Unix convention on both Darwin and Linux=
PPC,
-but offers (as of version 0.11) some support for reading and writing
-files that use the MacOS convention as well.</para>
-        <para>This support (and anything like it) is by nature heuristic: =
it
-can successfully hide the distinction between newline conventions
-much of the time, but could mistakenly change the meaning of
-otherwise correct programs (typically when files contain both
-#\Return and #\Linefeed characters or when files contain mixtures of
-text and binary data.) Because of this concern, the default settings
-of some of the variables that control newline translation and
-interpretation are somewhat conservative.</para>
-        <para>Although the issue of multiple newline conventions primarily
-affects MacOSX users, the functionality described here is available
-under LinuxPPC as well (and may occasionally be useful there.)</para>
-        <para>None of this addresses issues related
-to the third newline convention ("CRLF") in widespread use
-(since that convention isn't native to any platform on which
-OpenMCL currently runs). If OpenMCL is ever ported to such a
-platform, that issue might be revisited.</para>
-        <para>Note that some MacOS programs (including some versions of
-commercial MCL) may use HFS file type information to recognize TEXT
-and other file types and so may fail to recognize files created with
-OpenMCL or other Darwin applications (regardless of line termination
-issues.)</para>
-        <para>Unless otherwise noted, the symbols mentioned in this
-documentation are exported from the CCL package.</para>
+	<title>Line Termination Characters</title>
+        <para>MacOSX effectively supports two distinct line-termination
+	conventions. Programs in its Darwin substrate follow the Unix
+	convention of recognizing #\LineFeed as a line terminator; traditional
+	MacOS programs use #\Return for this purpose.  Many modern
+	GUI programs try to support several different line-termination
+	conventions (on the theory that the user shouldn't be too concerned
+	about what conventions are used an that it probably doesn't matter.
+	Sometimes this is true, other times ... not so much.
+	</para>
+        <para>OpenMCL follows the Unix convention on both Darwin and
+        LinuxPPC, but offers some support for reading and writing
+        files that use other conventions (including traditional MacOS
+        conventions) as well.</para> =

+	<para>This support (and anything like it) is by nature
+	heuristic: it can successfully hide the distinction between
+	newline conventions much of the time, but could mistakenly
+	change the meaning of otherwise correct programs (typically
+	when files contain both #\Return and #\Linefeed characters or
+	when files contain mixtures of text and binary data.) Because
+	of this concern, the default settings of some of the variables
+	that control newline translation and interpretation are
+	somewhat conservative.</para>
+	<para>Although the issue of multiple newline conventions
+	primarily affects MacOSX users, the functionality described
+	here is available under LinuxPPC as well (and may occasionally
+	be useful there.)</para> <para>None of this addresses issues
+	related to the third newline convention ("CRLF") in widespread
+	use (since that convention isn't native to any platform on
+	which OpenMCL currently runs). If OpenMCL is ever ported to
+	such a platform, that issue might be revisited.</para>
+	<para>Note that some MacOS programs (including some versions
+	of commercial MCL) may use HFS file type information to
+	recognize TEXT and other file types and so may fail to
+	recognize files created with OpenMCL or other Darwin
+	applications (regardless of line termination issues.)</para>
+	<para>Unless otherwise noted, the symbols mentioned in this
+	documentation are exported from the CCL package.</para>
       </sect2>
 =

       <sect2 id=3D"Single-precision-trig---transcendental-functions">
-        <para>Single-precision trig &amp; transcendental functions
-Despite what Darwin's man pages say, early versions of its math library
-(up to and including OSX 10.2 (Jaguar) don't implement
-single-precision variants of the transcendental and trig functions
-(#_sinf, #_atanf, etc.) OpenMCL works around this by coercing
-single-precision args to double-precision, calling the
-double-precision version of the math library function, and coercing
-the result back to a SINGLE-FLOAT. These steps can introduce rounding
-errors (and potentially overflow conditions) that might not be present
-or as severe if true 32-bit variants were available.</para>
+	<title>Single-precision trig &amp; transcendental functions</title>
+        <para>
+	Despite what Darwin's man pages say, early versions of its math library
+	(up to and including at least OSX 10.2 (Jaguar) don't implement
+	single-precision variants of the transcendental and trig functions
+	(#_sinf, #_atanf, etc.) OpenMCL worked around this by coercing
+	single-precision args to double-precision, calling the
+	double-precision version of the math library function, and coercing
+	the result back to a SINGLE-FLOAT. These steps can introduce rounding
+	errors (and potentially overflow conditions) that might not be present
+	or as severe if true 32-bit variants were available.</para>
       </sect2>
 =

       <sect2 id=3D"Shared-libraries">
-        <para>Shared libraries
-Darwin/MacOS X distinguishes between "shared libraries" and "bundles"
-or "extensions"; Linux doesn't. In Darwin, "shared libraries" have the
-file type "dylib" : the expectation is that this class of file is
-linked against when executable files are created and loaded by the OS
-when the executable is launched. The latter class -
-"bundles/extensions" - are expected to be loaded into and unloaded
-from a running application, via a mechanism like the one used by
-OpenMCL's OPEN-SHARED-LIBRARY function.</para>
-        <para>OpenMCL wants to treat all shared libs as if they were "bund=
les"; this
-is presumably possible, but none of it's implemented under OpenMCL
-0.10. Ideally, whatever gets implemented will hide the distinction as
-much as possible, but it may not be possible to hide it completely.</para>
+	<title>Shared libraries</title>
+        <para>Darwin/MacOS X distinguishes between "shared libraries"
+        and "bundles" or "extensions"; Linux and FreeBSD don't. In
+        Darwin, "shared libraries" have the file type "dylib" : the
+        expectation is that this class of file is linked against when
+        executable files are created and loaded by the OS when the
+        executable is launched. The latter class -
+        "bundles/extensions" - are expected to be loaded into and
+        unloaded from a running application, via a mechanism like the
+        one used by OpenMCL's OPEN-SHARED-LIBRARY function.</para>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"Unix-Posix-Darwin-Features">
-      <para>Unix/Posix/Darwin Features
-OpenMCL has several convenience functions which allow you to
-make Posix (portable Unix) calls without having to use the
-foreign-function interface.  Each of these corresponds directly
-to a single Posix function call, as it might be made in C.  There
-is no attempt to make these calls correspond to Lisp idioms, such as
-<literal>setf</literal>.  This means that their behaviour is
-simple and predictable.</para>
+      <title>Unix/Posix/Darwin Features</title>
+      <para>OpenMCL has several convenience functions which allow you
+      to make Posix (portable Unix) calls without having to use the
+      foreign-function interface.  Each of these corresponds directly
+      to a single Posix function call, as it might be made in C.
+      There is no attempt to make these calls correspond to Lisp
+      idioms, such as <literal>setf</literal>.  This means that their
+      behaviour is simple and predictable.</para>
       <para>For working with environment variables, there are
-CCL::GETENV and CCL::SETENV.</para>
+      CCL::GETENV and CCL::SETENV.</para>
       <para>For working with user and group IDs, there are
-CCL::GETUID, CCL::SETUID,
-and CCL::SETGID.  To find the home directory
-of an arbitrary user, as set in the user database (/etc/passwd),
-there is CCL::GET-USER-HOME-DIR.</para>
-      <para>For process IDs, there
-is CCL::GETPID.</para>
+      CCL::GETUID, CCL::SETUID, and CCL::SETGID.  To find the home
+      directory of an arbitrary user, as set in the user database
+      (/etc/passwd), there is CCL::GET-USER-HOME-DIR.</para>
+      <para>For process IDs, there is CCL::GETPID.</para>
       <para>For the <literal>system()</literal> function, there is
-CCL::OS-COMMAND.  Ordinarily, it is better -
-both more efficient and more predictable - to use the features
-described in .  However,
-sometimes you may want to specifically ask the shell to invoke a
-command for you.</para>
+      CCL::OS-COMMAND.  Ordinarily, it is better - both more efficient
+      and more predictable - to use the features described in <xref
+      linkend=3D"Running-Other-Programs-as-Subprocesses"/>.  However,
+      sometimes you may want to specifically ask the shell to invoke a
+      command for you.</para>
     </sect1>
 =

     <sect1 id=3D"Cocoa-Programming-in-OpenMCL">
-      <para>Cocoa Programming in OpenMCL
-Cocoa is one of Apple's APIs for GUI programming; for most purposes,
-development is considerably faster with Cocoa than with the
-alternatives.  You should have a little familiarity with it, to
-better understand this section.</para>
-      <para>A small sample Cocoa program can be invoked by evaluating (REQ=
UIRE
-'TINY) and then (CCL::TINY-SETUP). This program provides a simple
-example of using several of the bridge's capabilities.</para>
-      <para>The Tiny demo creates Cocoa objects dynamically, at runtime, w=
hich is
-always an option.  However, for large applications, it is usually more
-convenient to create your objects with Apple Interface Builder, and
-store them in .nib files to be loaded when needed.  Both approaches
-can be freely mixed in a single program.</para>
+      <title>Cocoa Programming in OpenMCL</title>
+      <para>Cocoa is one of Apple's APIs for GUI programming; for most
+      purposes, development is considerably faster with Cocoa than
+      with the alternatives.  You should have a little familiarity
+      with it, to better understand this section.</para>
+      <para>A small sample Cocoa program can be invoked by evaluating
+      (REQUIRE 'TINY) and then (CCL::TINY-SETUP). This program
+      provides a simple example of using several of the bridge's
+      capabilities.</para>
+      <para>The Tiny demo creates Cocoa objects dynamically, at
+      runtime, which is always an option.  However, for large
+      applications, it is usually more convenient to create your
+      objects with Apple Interface Builder, and store them in .nib
+      files to be loaded when needed.  Both approaches can be freely
+      mixed in a single program.</para>
 =

       <sect2 id=3D"The-Command-Line-and-the-Window-System">
-        <para>The Command Line and the Window System
-OpenMCL is ordinarily a command-line application (it doesn't have a
-connection to the OSX Window server, doesn't have its own menubar or
-dock icon, etc.) By opening some libraries and jumping through some
-hoops, it's able to sort of transform itself into a full-fledged GUI
-application (while retaining its original TTY-based listener.) The
-general idea is that this hybrid environment can be used to test and
-protoype UI ideas and the resulting application can eventually be
-fully transformed into a bundled, double-clickable application. This
-is to some degree possible, but there needs to be a bit more
-infrastructure in place before many people would find it easy.</para>
+	<title>The Command Line and the Window System</title>
+        <para>OpenMCL is ordinarily a command-line application (it
+        doesn't have a connection to the OSX Window server, doesn't
+        have its own menubar or dock icon, etc.) By opening some
+        libraries and jumping through some hoops, it's able to sort of
+        transform itself into a full-fledged GUI application (while
+        retaining its original TTY-based listener.) The general idea
+        is that this hybrid environment can be used to test and
+        protoype UI ideas and the resulting application can eventually
+        be fully transformed into a bundled, double-clickable
+        application. This is to some degree possible, but there needs
+        to be a bit more infrastructure in place before many people
+        would find it easy.</para>
         <para>Cocoa applications use the NSLog function to write
-informational/warning/error messages to the application's standard
-output stream. When launched by the Finder, a GUI application's
-standard output is diverted to a logging facility that can be
-monitored with the Console application (found in
-/Applications/Utilities/Console.app).  In the hybrid environment, the
-application's standard output stream is usually the initial listener's
-standard output stream. With two different buffered stream mechanisms
-trying to write to the same underlying Unix file descriptor, it's not
-uncommon to see NSLog output mixed with lisp output on the initial
-listener.</para>
+        informational/warning/error messages to the application's
+        standard output stream. When launched by the Finder, a GUI
+        application's standard output is diverted to a logging
+        facility that can be monitored with the Console application
+        (found in /Applications/Utilities/Console.app).  In the hybrid
+        environment, the application's standard output stream is
+        usually the initial listener's standard output stream. With
+        two different buffered stream mechanisms trying to write to
+        the same underlying Unix file descriptor, it's not uncommon to
+        see NSLog output mixed with lisp output on the initial
+        listener.</para>
       </sect2>
 =

       <sect2 id=3D"Writing--and-reading--Cocoa-code">
-        <para>Writing (and reading) Cocoa code
-The syntax of the constructs used to define Cocoa classes and methods
-has changed a bit (it was never documented outside of the source code
-and never too well documented at all), largely as the result of
-functionality offered by Randall Beer's bridge; the &ldquo;standard
-name-mapping conventions&rdquo; referenced below are described in his
-CocoaBridgeDoc.txt file, as are the constructs used to invoke (&ldquo;send
-messages to&rdquo;) Cocoa methods.</para>
+	<title>Writing (and reading) Cocoa code</title> <para>The
+	syntax of the constructs used to define Cocoa classes and
+	methods has changed a bit (it was never documented outside of
+	the source code and never too well documented at all), largely
+	as the result of functionality offered by Randall Beer's
+	bridge; the &ldquo;standard name-mapping conventions&rdquo;
+	referenced below are described in his CocoaBridgeDoc.txt file,
+	as are the constructs used to invoke (&ldquo;send messages
+	to&rdquo;) Cocoa methods.</para>
         <para>All of the symbols described below are currently internal to
 the CCL package.</para>
-        <colspec>
-          <thead cols=3D"1">
-            <tbody colwidth=3D"100*"></tbody>
-            <row>
-              <abstract>
-                <entry>CCL::@CLASS</entry>
-              =

-              </abstract>
-              <abstract>
-                <entry>CCL::@SELECTOR</entry>
-              =

-              </abstract>
-              <abstract>
-                <entry>CCL::DEFINE-OBJC-METHOD</entry>
-              =

-              </abstract>
-              <abstract>
-                <entry>CCL::DEFINE-OBJC-CLASS-METHOD</entry>
-              =

-              </abstract>
-            </row>
-          </thead>
-        </colspec>
+	<simplelist type=3D"vert" columns=3D"1">
+	  <member><xref linkend=3D"m_class"/></member>
+	  <member><xref linkend=3D"m_selector"/></member>
+	  <member><xref linkend=3D"m_define-objc-method"/></member>
+	  <member><xref linkend=3D"m_define-objc-class-method"/></member>
+	</simplelist>
       </sect2>
 =

       <sect2 id=3D"The-Application-Kit-and-Multiple-Threads">
-        <para>The Application Kit and Multiple Threads
-The Cocoa API is broken into several pieces.  The Application Kit,
-affectionately called AppKit, is the one which deals with window
-management, drawing, and handling events.  AppKit really wants all
-these things to be done by a "distinguished thread".  creation, and
-drawing to take place on a distinguished thread.</para>
-        <para>Apple has published some guidelines which discuss these issu=
es in some
-detail; see
-the Apple Multithreading Documentation, and in particular the guidelines
-on
-Using the Application Kit from Multiple Threads.  The upshot is that there
-can sometimes be unexpected behavior when objects are created in
-threads other than the distinguished event thread; eg, the event
-thread sometimes starts performing operations on objects that haven't
-been fully initialized.</para>
-        <para>It's certainly more convenient to do certain types of explor=
atory
-programming by typing things into a listener or evaluating a &ldquo;defun&=
rdquo;
-in an Emacs buffer; it may sometimes be necessary to be aware of this
-issue while doing so.</para>
-        <para>Each thread in the Cocoa runtime system is expected to maint=
ain a
-current &ldquo;autorelease pool&rdquo; (an instance of the NSAutoreleasePo=
ol
-class); newly created objects are often added to the current
-autorelease pool (via the -autorelease method), and periodically the
-current autorelease pool is sent a &ldquo;-release&rdquo; message, which c=
auses
-it to send &ldquo;-release&rdquo; messages to all of the objects that've b=
een
-added to it.</para>
-        <para>If the current thread doesn't have a current autorelease poo=
l, the
-attempt to autorelease any object will result in a severe-looking
-warning being written via NSLog. The event thread maintains an
-autorelease pool (it releases the current pool after each event is
-processed and creates a new one for the next event), so code that only
-runs in that thread should never provoke any of these severe-looking
-NSLog messages.</para>
-        <para>To try to suppress these messages (and still participate in =
the Cocoa
-memory management scheme), each listener thread (the initial listener
-and any created via the &ldquo;New Listener&rdquo; command in the IDE) is =
given
-a default autorelease pool; there are REPL colon-commands for
-manipulating the current listener's &ldquo;toplevel auturelease pool&rdquo=
;.</para>
-        <para>In the current scheme, every time that Cocoa calls lisp code=
, a lisp
-error handler is established which maps any lisp conditions to ObjC
-exceptions and arranges that this exception is raised when the
-callback to lisp returns. Whenever lisp code invokes a Cocoa method,
-it does so with an ObjC exception handler in place; this handler maps
-ObjC exceptions to lisp conditions and signals those conditions.</para>
-        <para>Any unhandled lisp error or ObjC exception that occurs durin=
g the
-execution of the distinguished event thread's event loop causes a
-message to be NSLog'ed and the event loop to (try to) continue
-execution. Any error that occurs in other threads is handled at the
-point of the outermost Cocoa method invocation. (Note that the error
-is not necessarily &ldquo;handled&rdquo; in the dynamic context in which it
-occurs.)</para>
+	<title>The Application Kit and Multiple Threads</title>
+        <para>The Cocoa API is broken into several pieces.  The
+        Application Kit, affectionately called AppKit, is the one
+        which deals with window management, drawing, and handling
+        events.  AppKit really wants all these things to be done by a
+        "distinguished thread".  creation, and drawing to take place
+        on a distinguished thread.</para>
+        <para>Apple has published some guidelines which discuss these
+        issues in some detail; see the Apple Multithreading
+        Documentation, and in particular the guidelines on Using the
+        Application Kit from Multiple Threads.  The upshot is that
+        there can sometimes be unexpected behavior when objects are
+        created in threads other than the distinguished event thread;
+        eg, the event thread sometimes starts performing operations on
+        objects that haven't been fully initialized.</para> <para>It's
+        certainly more convenient to do certain types of exploratory
+        programming by typing things into a listener or evaluating a
+        &ldquo;defun&rdquo; in an Emacs buffer; it may sometimes be
+        necessary to be aware of this issue while doing so.</para>
+        <para>Each thread in the Cocoa runtime system is expected to
+        maintain a current &ldquo;autorelease pool&rdquo; (an instance
+        of the NSAutoreleasePool class); newly created objects are
+        often added to the current autorelease pool (via the
+        -autorelease method), and periodically the current autorelease
+        pool is sent a &ldquo;-release&rdquo; message, which causes it
+        to send &ldquo;-release&rdquo; messages to all of the objects
+        that've been added to it.</para>
+        <para>If the current thread doesn't have a current autorelease
+        pool, the attempt to autorelease any object will result in a
+        severe-looking warning being written via NSLog. The event
+        thread maintains an autorelease pool (it releases the current
+        pool after each event is processed and creates a new one for
+        the next event), so code that only runs in that thread should
+        never provoke any of these severe-looking NSLog
+        messages.</para> <para>To try to suppress these messages (and
+        still participate in the Cocoa memory management scheme), each
+        listener thread (the initial listener and any created via the
+        &ldquo;New Listener&rdquo; command in the IDE) is given a
+        default autorelease pool; there are REPL colon-commands for
+        manipulating the current listener's &ldquo;toplevel
+        auturelease pool&rdquo;.</para>
+        <para>In the current scheme, every time that Cocoa calls lisp
+        code, a lisp error handler is established which maps any lisp
+        conditions to ObjC exceptions and arranges that this exception
+        is raised when the callback to lisp returns. Whenever lisp
+        code invokes a Cocoa method, it does so with an ObjC exception
+        handler in place; this handler maps ObjC exceptions to lisp
+        conditions and signals those conditions.</para> <para>Any
+        unhandled lisp error or ObjC exception that occurs during the
+        execution of the distinguished event thread's event loop
+        causes a message to be NSLog'ed and the event loop to (try to)
+        continue execution. Any error that occurs in other threads is
+        handled at the point of the outermost Cocoa method
+        invocation. (Note that the error is not necessarily
+        &ldquo;handled&rdquo; in the dynamic context in which it
+        occurs.)</para>
         <para>Both of these behaviors could possibly be improved; both of =
them
 seem to be substantial improvements over previous behaviors (where,
 for instance, a misspelled message name typically terminated the
@@ -8806,23 +12117,24 @@
       </sect2>
 =

       <sect2 id=3D"Acknowledgement--2-">
-        <para>Acknowledgement
-The Cocoa bridge was originally developed, and generously contributed
-by, Randal Beer.</para>
+	<title>Acknowledgement</title>
+        <para>The Cocoa bridge was originally developed, and
+        generously contributed by, Randal Beer.</para>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"Building-an-Application-Bundle">
-      <para>Building an Application Bundle
-You may have noticed that (require "COCOA") takes a long time to load.
-It is possible to avoid this by saving a Lisp heap image which has
-everything already loaded.  There is an example file which allows you
-to do this, "ccl/examples/cocoa-application.lisp", by producing a
-double-clickable application which runs your program.  First, load
-your own program.  Then, do:</para>
+      <title>Building an Application Bundle</title>
+      <para>You may have noticed that (require "COCOA") takes a long
+      time to load.  It is possible to avoid this by saving a Lisp
+      heap image which has everything already loaded.  There is an
+      example file which allows you to do this,
+      "ccl/examples/cocoa-application.lisp", by producing a
+      double-clickable application which runs your program.  First,
+      load your own program.  Then, do:</para>
       <programlisting>
 ? (require "COCOA-APPLICATION")
-</programlisting>
+      </programlisting>
       <para>When it finishes, you should be able to double-click the OpenM=
CL icon
 in the ccl directory, to quickly start your program.</para>
       <para>The OS may have already decided that OpenMCL.app isn't a valid
@@ -8855,512 +12167,980 @@
     </sect1>
 =

     <sect1 id=3D"Recommended-Reading">
-      <para>Recommended Reading</para>
-      <term><indexterm>Cocoa Documentation
-          <variablelist>This is the top page for all of Apple's documentat=
ion onCocoa.  If you are unfamiliar with Cocoa, it is a goodplace to start.=
</variablelist>
-        </indexterm><indexterm>Foundation Reference for Objective-C
-          <variablelist>This is one of the two most important Cocoa refere=
nces; itcovers all of the basics, except for GUI programming.  This isa ref=
erence, not a tutorial.</variablelist>
-        </indexterm><indexterm>Application Kit Reference for Objective-C
-          <variablelist>This is the other; it covers GUI programming with =
Cocoain considerable depth.  This is a reference, not a tutorial.</variable=
list>
-        </indexterm><indexterm>Apple Developer Documentation
-          <variablelist>This is the site which the above two documents are=
 found on;go here to find the documentation on any other Apple API.Also go =
here if you need general guidance about OS X, Carbon,Cocoa, Core Foundation=
, or Objective C.</variablelist>
-        </indexterm>
-      </term>
+      <title>Recommended Reading></title>
+      <variablelist>
+	<varlistentry>
+	   <term>
+	     <ulink url=3D"http://developer.apple.com/documentation/Cocoa/">Cocoa=
 Documentation</ulink>
+	   </term>
+
+	   <listitem>
+	     <para>
+	       This is the top page for all of Apple's documentation on
+	       Cocoa.  If you are unfamiliar with Cocoa, it is a good
+	       place to start.
+	     </para>
+	   </listitem>
+	</varlistentry>
+	<varlistentry>
+	  <term>
+	    <ulink url=3D"http://developer.apple.com/documentation/Cocoa/Referenc=
e/Foundation/ObjC_classic/index.html">Foundation Reference for Objective-C<=
/ulink>
+	  </term>
+
+	  <listitem>
+	    <para>
+	      This is one of the two most important Cocoa references; it
+	      covers all of the basics, except for GUI programming.  This is
+	      a reference, not a tutorial.
+	    </para>
+	  </listitem>
+	</varlistentry>
+
+	<varlistentry>
+	  <term>
+	    <ulink url=3D"http://developer.apple.com/documentation/Cocoa/Referenc=
e/ApplicationKit/ObjC_classic/index.html">Application Kit Reference for Obj=
ective-C</ulink>
+	  </term>
+
+	  <listitem>
+	    <para>
+	      This is the other; it covers GUI programming with Cocoa
+	      in considerable depth.  This is a reference, not a tutorial.
+	    </para>
+	  </listitem>
+	</varlistentry>
+
+	<varlistentry>
+	  <term>
+	    <ulink url=3D"http://developer.apple.com/documentation/index.html">Ap=
ple Developer Documentation</ulink>
+	  </term>
+
+	  <listitem>
+	    <para>
+	      This is the site which the above two documents are found on;
+	      go here to find the documentation on any other Apple API.
+	      Also go here if you need general guidance about OS X, Carbon,
+	      Cocoa, Core Foundation, or Objective C.
+	    </para>
+	  </listitem>
+	</varlistentry>
+      </variablelist>
+
     </sect1>
 =

     <sect1 id=3D"Operating-System-Dictionary">
-      <para>Operating-System Dictionary</para>
-
-      <sect2 id=3D"CCL--GETENV">
-        <para>CCL::GETENV</para>
-        <informalfigure>getenv</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::GETENV &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-getenv name =3D> value
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>a string which is the name of an existingenviron=
ment variable;case-sensitive</variablelist>
-          </indexterm><indexterm>value
-            <variablelist>if there is an environment variable named<litera=
l>name</literal>, its value, as a string; if thereis not, NIL</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Looks up the value of the environment variable named by
-<literal>name</literal>, in the OS environment.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--SETENV">
-        <para>CCL::SETENV</para>
-        <informalfigure>setenv</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::SETENV &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-setenv name value =3D> errno
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>a string which is the name of a new or existinge=
nvironment variable;case-sensitive</variablelist>
-          </indexterm><indexterm>value
-            <variablelist>a string, to be the new value of theenvironment =
variablenamed by <literal>name</literal></variablelist>
-          </indexterm><indexterm>errno
-            <variablelist>zero if the function call completes successfully=
;otherwise, a platform-dependent integer which describesthe problem</variab=
lelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Sets the value of the environment variable named by
-<literal>name</literal>, in the OS environment.  If there is
-no such environment
-variable, creates it.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--CURRENT-DIRECTORY-NAME">
-        <para>CCL::CURRENT-DIRECTORY-NAME</para>
-        <informalfigure>current-directory-name</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::CURRENT-DIRECTORY-NAME &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-current-directory-name
-	  =3D> path
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>path
-            <variablelist>a string, an absolute pathname in Posix format -=
 withdirectory components separated by slashes</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Looks up the current working directory of the OpenMCL proces=
s;
-unless it has been changed, this is the directory OpenMCL was
-started in.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--GETUID">
-        <para>CCL::GETUID</para>
-        <informalfigure>getuid</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::GETUID &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-getuid =3D> uid
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>uid
-            <variablelist>a non-negative integer, identifying a specific u=
seraccount as defined in the OS user database</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the ("real") user ID of the current user.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--SETUID">
-        <para>CCL::SETUID</para>
-        <informalfigure>setuid</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::SETUID &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-setuid uid =3D> errno
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>uid
-            <variablelist>a non-negative integer, identifying a specific u=
seraccount as defined in the OS user database</variablelist>
-          </indexterm><indexterm>errno
-            <variablelist>zero if the function call completes successfully=
;otherwise, a platform-dependent integer which describesthe problem</variab=
lelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Attempts to change the current user ID (both "real" and
-"effective"); fails unless
-the OpenMCL process has super-user privileges or the ID
-given is that of the current user.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--SETGID">
-        <para>CCL::SETGID</para>
-        <informalfigure>setgid</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::SETGID &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-setgid gid =3D> errno
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>gid
-            <variablelist>a non-negative integer, identifying a specificgr=
oup as defined in the OS user database</variablelist>
-          </indexterm><indexterm>errno
-            <variablelist>zero if the function call completes successfully=
;otherwise, a platform-dependent integer which describesthe problem</variab=
lelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Attempts to change the current group ID (both "real" and
-"effective"); fails unless
-the OpenMCL process has super-user privileges or the ID
-given is that of a group to which the current user belongs.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--GETPID">
-        <para>CCL::GETPID</para>
-        <informalfigure>getpid</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::GETPID &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-getpid =3D> pid
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>pid
-            <variablelist>a non-negative integer, identifying an OS proces=
s</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the ID of the OpenMCL OS process.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--GET-USER-HOME-DIR">
-        <para>CCL::GET-USER-HOME-DIR</para>
-        <informalfigure>get-user-home-dir</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::GET-USER-HOME-DIR &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-get-user-home-dir
-	  uid =3D> path
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>uid
-            <variablelist>a non-negative integer, identifying a specific u=
seraccount as defined in the OS user database</variablelist>
-          </indexterm><indexterm>path
-            <variablelist>a string, an absolute pathname in Posix format -=
 withdirectory components separated by slashes; or NIL</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Looks up and returns the defined home directory of the user
-identified by <literal>uid</literal>.  This value comes from the
-OS user database, not from the <literal>$HOME</literal>
-environment variable.  Returns NIL if there is no user with
-the ID <literal>uid</literal>.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--OS-COMMAND">
-        <para>CCL::OS-COMMAND</para>
-        <informalfigure>os-command</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::OS-COMMAND &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-os-command command-line
-	  =3D> exit-code
-</programlisting>
-        <bridgehead renderas=3D"sect3">Values</bridgehead>
-        <term><indexterm>command-line
-            <variablelist>a string, obeying all the whitespace andescaping=
conventions required by the user's default system shell</variablelist>
-          </indexterm>
-        </term>
-        <term><indexterm>exit-code
-            <variablelist>a non-negative integer, returned as the exitcode=
 of a subprocess; zero indicates success</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Invokes the Posix function <literal>system()</literal>, which
-invokes the user's default system shell (such as
-sh or tcsh) as a new process, and has that shell execute
-<literal>command-line</literal>.</para>
-        <para>If the shell was able to find the command specified in
-<literal>command-line</literal>, then <literal>exit-code</literal>
-is the exit code of that command.  If not, it is the exit
-code of the shell itself.</para>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para>By convention, an exit code of 0 indicates success.  There a=
re
-also other conventions; unfortunately, they are OS-specific, and
-the portable macros to decode their meaning are implemented
-by the system headers as C preprocessor macros.  This means
-that there is no good, automated way to make them available
-to Lisp.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL----CLASS">
-        <para>CCL::@CLASS</para>
-        <informalfigure>@class</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::@CLASS &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
- at class class-name
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>class-name
-            <variablelist>a string which denotes an existing class name, o=
r asymbol which can be mapped to such a string via the standardname-mapping=
 conventions for class names</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Used to refer to a known ObjC class by name. (Via the use
-LOAD-TIME-VALUE, the results of a class-name -> class lookup
-are cached.)</para>
-        <para><literal>@class</literal> is obsolete as of late 2004, becau=
se
-find-class now works on ObjC classes.  It is described here
-only because some old code still uses it.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL----SELECTOR">
-        <para>CCL::@SELECTOR</para>
-        <informalfigure>@selector</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::@SELECTOR &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
- at selector string
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>string
-            <variablelist>a string constant, used to canonically refer to =
anObjC method selector</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Used to refer to an ObjC method selector (method name). Uses
-LOAD-TIME-VALUE to cache the result of a string -> selector
-lookup.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--DEFINE-OBJC-METHOD">
-        <para>CCL::DEFINE-OBJC-METHOD</para>
-        <informalfigure>define-objc-method</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::DEFINE-OBJC-METHOD &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-define-objc-method
-	    (selector class-name) &amp;body body
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>selector
-            <variablelist>either a string which represents the name of the=
selector or a list which describ+es the method's returntype, selector compo=
nents, and argument types (see below.)If the first form is used, then the f=
irst form in the bodymust be a list which describes the selector's argument=
types and return value type, as per DEFCALLBACK.</variablelist>
-          </indexterm><indexterm>class-name
-            <variablelist>either a string which names an existing ObjC cla=
ssname or a list symbol which can map to such a string via thestandard name=
-mapping conventions for class names. (Notethat the "canonical" lisp class =
name is such asymbol)</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Defines an ObjC-callable method which implements the
-specified message selector for instances of the existing ObjC
-class class-name.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--DEFINE-OBJC-CLASS-METHOD">
-        <para>CCL::DEFINE-OBJC-CLASS-METHOD</para>
-        <informalfigure>define-objc-class-method</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::DEFINE-OBJC-CLASS-METHOD &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-define-objc-class-method
-	    (selector class-name) &amp;body body
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <para>As per DEFINE-OBJC-METHOD</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Like DEFINE-OBJC-METHOD, only used to define methods on the
-<emphasis>class</emphasis> named by class-name and on its
-subclasses.</para>
-        <para>For both DEFINE-OBJC-METHOD and DEFINE-OBJC-CLASS-METHOD, the
-"selector" argument can be a list whose first element is a
-foreign type specifier for the method's return value type and whose
-subsequent elements are either:</para>
-        <listitem mark=3D"bullet">
-          <variablelist>a non-keyword symbol, which can be mapped to a sel=
ector stringfor a parameterless method according to the standard name-mappi=
ngconventions for method selectors.</variablelist>
-          <variablelist>a list of alternating keywords and variable/type s=
pecifiers,where the set of keywords can be mapped to a selector string for =
aparameteriezed method according to the standard name-mappingconventions fo=
r method selectors and each variable/type-specifier iseither a variable nam=
e (denoting a value of type :ID) or a list whoseCAR is a variable name and =
whose CADR is the correspondingargument's foreign type specifier.</variable=
list>
-        =

-        </listitem>
-      </sect2>
-
-      <sect2 id=3D"CCL--ALTERNATE-LINE-TERMINATOR-">
-        <para>CCL:*ALTERNATE-LINE-TERMINATOR*</para>
-        <informalfigure>*alternate-line-terminator*</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL:*ALTERNATE-LINE-TERMINATOR* &mdash;</para>
-        <para>Variable</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>This variable is currently only used by the standard reader =
macro
-function for #\; (single-line comments); that function reads successive
-characters until EOF, a #\NewLine is read, or a character EQL to the
-value of *alternate-line-terminator* is read. In OpenMCL for Darwin, the
-value of this variable is initially #\Return ; in OpenMCL for LinuxPPC,
-it's initially NIL.</para>
-        <para>Their default treatment by the #\; reader macro is the prima=
ry way
-in which #\Return and #\Linefeed differ syntactally; by extending the
-#\; reader macro to (conditionally) treat #\Return as a
-comment-terminator, that distinction is eliminated. This seems to make
-LOAD and COMPILE-FILE insensitive to line-termination issues in many
-cases. It could fail in the (hopefully rare) case where a LF-terminated
-(Unix) text file contains embedded #\Return characters, and this
-mechanism isn't adequate to handle cases where newlines are embedded
-in string constants or other tokens (and presumably should be translated
-from an external convention to the external one) : it doesn't change
-what READ-CHAR or READ-LINE "see", and that may be necessary to
-handle some more complicated cases.</para>
-      </sect2>
-
-      <sect2 id=3D"iEXTERNAL-FORMAT">
-        <para>:EXTERNAL-FORMAT</para>
-        <informalfigure>:external-format</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>:EXTERNAL-FORMAT &mdash;</para>
-        <para>Keyword Argument</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Per ANSI CL, OpenMCL supports the :EXTERNAL-FORMAT keyword
-argument to the functions OPEN, LOAD, and COMPILE-FILE. This argument is
-intended to provide a standard way of providing implementation-dependent
-information about the format of files opened with an element-type of
-CHARACTER. This argument can meaningfully take on the values :DEFAULT
-(the default), :MACOS, :UNIX, or :INFERRED in OpenMCL.</para>
-        <para>When defaulted to or specified as :DEFAULT, the format of th=
e file
-stream is determined by the value of the variable
-CCL:*DEFAULT-EXTERNAL-FORMAT*. See below.</para>
-        <para>When specified as :UNIX, all characters are read from and wr=
itten
-to files verbatim.</para>
-        <para>When specified as :MACOS, all #\Return characters read from =
the
-file are immediately translated to #\Linefeed (#\Newline); all #\Newline
-(#\Linefeed) characters are written externally as #\Return characters.</pa=
ra>
-        <para>When specified as :INFERRED and the file is open for input, =
the
-first bufferful of input data is examined; if a #\Return character
-appears in the buffer before the first #\Linefeed, the file stream's
-external-format is set to :MACOS; otherwise, it is set to :UNIX.</para>
-        <para>All other values of :EXTERNAL-FORMAT - and any combinations =
that
-don't make sense, such as trying to infer the format of a
-newly-created output file stream - are treated as if :UNIX was
-specified. As mentioned above, the :EXTERNAL-FORMAT argument doesn't
-apply to binary file streams.</para>
-        <para>The translation performed when :MACOS is specified or inferr=
ed has
-a somewhat greater chance of doing the right thing than the
-*alternate-line-terminator* mechanism does; it probably has a somewhat
-greater chance of doing the wrong thing, as well.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--DEFAULT-EXTERNAL-FORMAT-">
-        <para>CCL:*DEFAULT-EXTERNAL-FORMAT*</para>
-        <informalfigure>*default-external-format*</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL:*DEFAULT-EXTERNAL-FORMAT* &mdash;</para>
-        <para>Variable</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>The value of this variable is used when :EXTERNAL-FORMAT is
-unspecified or specified as :DEFAULT. It can meaningfully be given any
-of the values :UNIX, :MACOS, or :INFERRED, each of which is interpreted
-as described above.</para>
-        <para>Because there's some risk that unsolicited newline translati=
on
-could have undesirable consequences, the initial value of this variable
-in OpenMCL is :UNIX.</para>
-      </sect2>
-
-      <sect2 id=3D"CCL--NS-LISP-STRING">
-        <para>CCL::NS-LISP-STRING</para>
-        <informalfigure>ns-lisp-string</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CCL::NS-LISP-STRING &mdash;</para>
-        <para>Class</para>
-        <bridgehead renderas=3D"sect3">Superclasses</bridgehead>
-        <para>NS:NS-STRING</para>
-        <bridgehead renderas=3D"sect3">Initargs</bridgehead>
-        <term><indexterm>:string
-            <variablelist>a Lisp string which is to be the content ofthe n=
ewly-created ns-lisp-string.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>This class
-implements the interface of an NSString, which means that it can
-be passed to any Cocoa or Core Foundation function which expects
-one.</para>
-        <para>The string itself is stored on the Lisp heap, which
-means that its memory management is automatic.  However, the
-ns-lisp-string object itself is a foreign
-object (that is, it has an objc metaclass), and resides on the
-foreign heap.  Therefore, it is necessary to explicitly free
-it, by sending a dealloc message.</para>
-        <bridgehead renderas=3D"sect3">Examples</bridgehead>
-        <para>You can create an ns-lisp-string with
-<literal>make-instance</literal>, just like
-any normal Lisp class:</para>
-        <programlisting>
-? (defvar *the-string*
+      <title>Operating-System Dictionary</title>
+
+      <refentry id=3D"f_getenv">
+	<indexterm zone=3D"f_getenv">
+	  <primary>getenv</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::GETENV</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>getenv</function> name =3D> value</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>name</term>
+
+	      <listitem>
+		<para>a string which is the name of an existing
+		environment variable;
+		case-sensitive</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>value</term>
+
+	      <listitem>
+		<para>if there is an environment variable named
+		<varname>name</varname>, its value, as a string; if there
+		is not, NIL</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>
+	    Looks up the value of the environment variable named by
+	    <varname>name</varname>, in the OS environment.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_setenv">
+	<indexterm zone=3D"f_setenv">
+	  <primary>setenv</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::SETENV</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>setenv</function> name value =3D> errno</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>name</term>
+
+	      <listitem>
+		<para>a string which is the name of a new or existing
+		environment variable;
+		case-sensitive</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>value</term>
+
+	      <listitem>
+		<para>a string, to be the new value of the
+		environment variable
+		named by <varname>name</varname></para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>errno</term>
+
+	      <listitem>
+		<para>zero if the function call completes successfully;
+		otherwise, a platform-dependent integer which describes
+		the problem</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>
+	    Sets the value of the environment variable named by
+	    <varname>name</varname>, in the OS environment.  If there is
+	    no such environment
+	    variable, creates it.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_current-directory-name">
+	<indexterm zone=3D"f_current-directory-name">
+	  <primary>current-directory-name</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::CURRENT-DIRECTORY-NAME</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>current-directory-name</function>
+	  =3D> path</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>path</term>
+
+	      <listitem>
+		<para>a string, an absolute pathname in Posix format - with
+		directory components separated by slashes</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>
+	    Looks up the current working directory of the OpenMCL process;
+	    unless it has been changed, this is the directory OpenMCL was
+	    started in.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_getuid">
+	<indexterm zone=3D"f_getuid">
+	  <primary>getuid</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::GETUID</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>getuid</function> =3D> uid</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>uid</term>
+
+	      <listitem>
+		<para>a non-negative integer, identifying a specific user
+		account as defined in the OS user database</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>
+	    Returns the ("real") user ID of the current user.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_setuid">
+	<indexterm zone=3D"f_setuid">
+	  <primary>setuid</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::SETUID</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>setuid</function> uid =3D> errno</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>uid</term>
+
+	      <listitem>
+		<para>a non-negative integer, identifying a specific user
+		account as defined in the OS user database</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>errno</term>
+
+	      <listitem>
+		<para>zero if the function call completes successfully;
+		otherwise, a platform-dependent integer which describes
+		the problem</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>
+	    Attempts to change the current user ID (both "real" and
+	    "effective"); fails unless
+	    the OpenMCL process has super-user privileges or the ID
+	    given is that of the current user.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_setgid">
+	<indexterm zone=3D"f_setgid">
+	  <primary>setgid</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::SETGID</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>setgid</function> gid =3D> errno</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>gid</term>
+
+	      <listitem>
+		<para>a non-negative integer, identifying a specific
+		group as defined in the OS user database</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>errno</term>
+
+	      <listitem>
+		<para>zero if the function call completes successfully;
+		otherwise, a platform-dependent integer which describes
+		the problem</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>
+	    Attempts to change the current group ID (both "real" and
+	    "effective"); fails unless
+	    the OpenMCL process has super-user privileges or the ID
+	    given is that of a group to which the current user belongs.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_getpid">
+	<indexterm zone=3D"f_getpid">
+	  <primary>getpid</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::GETPID</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>getpid</function> =3D> pid</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>pid</term>
+
+	      <listitem>
+		<para>a non-negative integer, identifying an OS process</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>
+	    Returns the ID of the OpenMCL OS process.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_get-user-home-dir">
+	<indexterm zone=3D"f_get-user-home-dir">
+	  <primary>get-user-home-dir</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::GET-USER-HOME-DIR</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>get-user-home-dir</function> =

+	  uid =3D> path</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>uid</term>
+
+	      <listitem>
+		<para>a non-negative integer, identifying a specific user
+		account as defined in the OS user database</para>
+	      </listitem>
+	    </varlistentry>
+	    <varlistentry>
+	      <term>path</term>
+
+	      <listitem>
+		<para>a string, an absolute pathname in Posix format - with
+		directory components separated by slashes; or NIL</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>
+	    Looks up and returns the defined home directory of the user
+	    identified by <varname>uid</varname>.  This value comes from the
+	    OS user database, not from the <varname>$HOME</varname>
+	    environment variable.  Returns NIL if there is no user with
+	    the ID <varname>uid</varname>.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_os-command">
+	<indexterm zone=3D"f_os-command">
+	  <primary>os-command</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::OS-COMMAND</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>os-command</function> command-line
+	  =3D> exit-code</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>command-line</term>
+
+	      <listitem><para>a string, obeying all the whitespace and
+	      escaping
+	      conventions required by the user's default system shell</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	  <variablelist>
+	    <varlistentry>
+	      <term>exit-code</term>
+
+	      <listitem><para>a non-negative integer, returned as the exit
+	      code of a subprocess; zero indicates success</para></listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>
+	    Invokes the Posix function <function>system()</function>, which
+	    invokes the user's default system shell (such as
+	    sh or tcsh) as a new process, and has that shell execute
+	    <varname>command-line</varname>.
+	  </para>
+	  =

+	  <para>
+	    If the shell was able to find the command specified in
+	    <varname>command-line</varname>, then <varname>exit-code</varname>
+	    is the exit code of that command.  If not, it is the exit
+	    code of the shell itself.
+	  </para>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>
+	    By convention, an exit code of 0 indicates success.  There are
+	    also other conventions; unfortunately, they are OS-specific, and
+	    the portable macros to decode their meaning are implemented
+	    by the system headers as C preprocessor macros.  This means
+	    that there is no good, automated way to make them available
+	    to Lisp.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"m_class">
+	<indexterm zone=3D"m_class">
+	  <primary>@class</primary>
+	</indexterm>
+	=

+	<refnamediv>
+	  <refname>CCL::@CLASS</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>@class</function> class-name</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>class-name</term>
+
+	      <listitem>
+		<para>a string which denotes an existing class name, or a
+		symbol which can be mapped to such a string via the standard
+		name-mapping conventions for class names</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Used to refer to a known ObjC class by name. (Via the use
+	  LOAD-TIME-VALUE, the results of a class-name -&#62; class lookup
+	  are cached.)</para>
+
+	  <para>
+	    <function>@class</function> is obsolete as of late 2004, because
+	    find-class now works on ObjC classes.  It is described here
+	    only because some old code still uses it.
+	  </para>
+	</refsect1>
+	</refentry>
+
+	<refentry id=3D"m_selector">
+	  <indexterm zone=3D"m_selector">
+	    <primary>@selector</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>CCL::@SELECTOR</refname>
+	    <refpurpose></refpurpose>
+	    <refclass>Macro</refclass>
+	  </refnamediv>
+
+	  <refsynopsisdiv>
+	    <synopsis><function>@selector</function> string</synopsis>
+	  </refsynopsisdiv>
+
+	  <refsect1>
+	    <title>Arguments and Values</title>
+
+	    <variablelist>
+	      <varlistentry>
+		<term>string</term>
+
+		<listitem>
+		  <para>a string constant, used to canonically refer to an
+		  ObjC method selector</para>
+		</listitem>
+	      </varlistentry>
+	    </variablelist>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>Used to refer to an ObjC method selector (method name). Uses
+	    LOAD-TIME-VALUE to cache the result of a string -&#62; selector
+	    lookup.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"m_define-objc-method">
+	  <indexterm zone=3D"m_define-objc-method">
+	    <primary>define-objc-method</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>CCL::DEFINE-OBJC-METHOD</refname>
+	    <refpurpose></refpurpose>
+	    <refclass>Macro</refclass>
+	  </refnamediv>
+
+	  <refsynopsisdiv>
+	    <synopsis><function>define-objc-method</function>
+	    (selector class-name) &body; body</synopsis>
+	  </refsynopsisdiv>
+
+	  <refsect1>
+	    <title>Arguments and Values</title>
+
+	    <variablelist>
+	      <varlistentry>
+		<term>selector</term>
+
+		<listitem>
+		  <para>either a string which represents the name of the
+		  selector or a list which describ+es the method's return
+		  type, selector components, and argument types (see below.)
+		  If the first form is used, then the first form in the body
+		  must be a list which describes the selector's argument
+		  types and return value type, as per DEFCALLBACK.</para>
+		</listitem>
+	      </varlistentry>
+
+	      <varlistentry>
+		<term>class-name</term>
+
+		<listitem>
+		  <para>either a string which names an existing ObjC class
+		  name or a list symbol which can map to such a string via the
+		  standard name-mapping conventions for class names. (Note
+		  that the "canonical" lisp class name is such a
+		  symbol)</para>
+		</listitem>
+	      </varlistentry>
+	    </variablelist>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>Defines an ObjC-callable method which implements the
+	    specified message selector for instances of the existing ObjC
+	    class class-name.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"m_define-objc-class-method">
+	  <indexterm zone=3D"m_define-objc-class-method">
+	    <primary>define-objc-class-method</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>CCL::DEFINE-OBJC-CLASS-METHOD</refname>
+	    <refpurpose></refpurpose>
+	    <refclass>Macro</refclass>
+	  </refnamediv>
+
+	  <refsynopsisdiv>
+	    <synopsis><function>define-objc-class-method</function>
+	    (selector class-name) &body; body</synopsis>
+	  </refsynopsisdiv>
+
+	  <refsect1>
+	    <title>Arguments and Values</title>
+
+	    <para>As per DEFINE-OBJC-METHOD</para>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>Like DEFINE-OBJC-METHOD, only used to define methods on the
+	    <emphasis>class</emphasis> named by class-name and on its
+	    subclasses.</para>
+
+	    <para>For both DEFINE-OBJC-METHOD and DEFINE-OBJC-CLASS-METHOD, the
+	    "selector" argument can be a list whose first element is a
+	    foreign type specifier for the method's return value type and whose
+	    subsequent elements are either:</para>
+
+	    <itemizedlist>
+	      <listitem>
+		<para>a non-keyword symbol, which can be mapped to a selector string
+		for a parameterless method according to the standard name-mapping
+		conventions for method selectors.</para>
+	      </listitem>
+	      =

+	      <listitem>
+		<para>a list of alternating keywords and variable/type specifiers,
+		where the set of keywords can be mapped to a selector string for a
+		parameteriezed method according to the standard name-mapping
+		conventions for method selectors and each variable/type-specifier is
+		either a variable name (denoting a value of type :ID) or a list whose
+		CAR is a variable name and whose CADR is the corresponding
+		argument's foreign type specifier.</para>
+	      </listitem>
+	    </itemizedlist>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"v_alternate-line-terminator">
+	  <indexterm zone=3D"v_alternate-line-terminator">
+	    <primary>*alternate-line-terminator*</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>CCL:*ALTERNATE-LINE-TERMINATOR*</refname>
+	    <refpurpose></refpurpose>
+	    <refclass>Variable</refclass>
+	  </refnamediv>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>This variable is currently only used by the standard reader mac=
ro
+	    function for #\; (single-line comments); that function reads successi=
ve
+	    characters until EOF, a #\NewLine is read, or a character EQL to the
+	    value of *alternate-line-terminator* is read. In OpenMCL for Darwin, =
the
+	    value of this variable is initially #\Return ; in OpenMCL for LinuxPP=
C,
+	    it&#39;s initially NIL.</para>
+	    =

+	    <para>Their default treatment by the #\; reader macro is the primary =
way
+	    in which #\Return and #\Linefeed differ syntactally; by extending the
+	    #\; reader macro to (conditionally) treat #\Return as a
+	    comment-terminator, that distinction is eliminated. This seems to make
+	    LOAD and COMPILE-FILE insensitive to line-termination issues in many
+	    cases. It could fail in the (hopefully rare) case where a LF-terminat=
ed
+	    (Unix) text file contains embedded #\Return characters, and this
+	    mechanism isn&#39;t adequate to handle cases where newlines are embed=
ded
+	    in string constants or other tokens (and presumably should be transla=
ted
+	    from an external convention to the external one) : it doesn&#39;t cha=
nge
+	    what READ-CHAR or READ-LINE &#34;see&#34;, and that may be necessary =
to
+	    handle some more complicated cases.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"k_external-format">
+	  <indexterm zone=3D"k_external-format">
+	    <primary>:external-format</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>:EXTERNAL-FORMAT</refname>
+	    <refpurpose></refpurpose>
+	    <refclass>Keyword Argument</refclass>
+	  </refnamediv>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>Per ANSI CL, OpenMCL supports the :EXTERNAL-FORMAT keyword
+	    argument to the functions OPEN, LOAD, and COMPILE-FILE. This argument=
 is
+	    intended to provide a standard way of providing implementation-depend=
ent
+	    information about the format of files opened with an element-type of
+	    CHARACTER. This argument can meaningfully take on the values :DEFAULT
+	    (the default), :MACOS, :UNIX, or :INFERRED in OpenMCL.</para>
+	    =

+	    <para>When defaulted to or specified as :DEFAULT, the format of the f=
ile
+	    stream is determined by the value of the variable
+	    CCL:*DEFAULT-EXTERNAL-FORMAT*. See below.</para>
+	    =

+	    <para>When specified as :UNIX, all characters are read from and writt=
en
+	    to files verbatim.</para>
+	    =

+	    <para>When specified as :MACOS, all #\Return characters read from the
+	    file are immediately translated to #\Linefeed (#\Newline); all #\Newl=
ine
+	    (#\Linefeed) characters are written externally as #\Return characters=
.</para>
+	    =

+	    <para>When specified as :INFERRED and the file is open for input, the
+	    first bufferful of input data is examined; if a #\Return character
+	    appears in the buffer before the first #\Linefeed, the file stream&#3=
9;s
+	    external-format is set to :MACOS; otherwise, it is set to :UNIX.</par=
a>
+	    =

+	    <para>All other values of :EXTERNAL-FORMAT - and any combinations that
+	    don&#39;t make sense, such as trying to infer the format of a
+	    newly-created output file stream - are treated as if :UNIX was
+	    specified. As mentioned above, the :EXTERNAL-FORMAT argument doesn&#3=
9;t
+	    apply to binary file streams.</para>
+	    =

+	    <para>The translation performed when :MACOS is specified or inferred =
has
+	    a somewhat greater chance of doing the right thing than the
+	    *alternate-line-terminator* mechanism does; it probably has a somewhat
+	    greater chance of doing the wrong thing, as well.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"v_default-external-format">
+	  <indexterm zone=3D"v_default-external-format">
+	    <primary>*default-external-format*</primary>
+	  </indexterm>
+	  =

+	  <refnamediv>
+	    <refname>CCL:*DEFAULT-EXTERNAL-FORMAT*</refname>
+	    <refpurpose></refpurpose>
+	    <refclass>Variable</refclass>
+	  </refnamediv>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>The value of this variable is used when :EXTERNAL-FORMAT is
+	    unspecified or specified as :DEFAULT. It can meaningfully be given any
+	    of the values :UNIX, :MACOS, or :INFERRED, each of which is interpret=
ed
+	    as described above.</para>
+	    =

+	    <para>Because there&#39;s some risk that unsolicited newline translat=
ion
+	    could have undesirable consequences, the initial value of this variab=
le
+	    in OpenMCL is :UNIX.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id=3D"c_ns-lisp-string">
+	  <indexterm zone=3D"c_ns-lisp-string">
+	    <primary>ns-lisp-string</primary>
+	  </indexterm>
+
+	  <refnamediv>
+	    <refname>CCL::NS-LISP-STRING</refname>
+	    <refpurpose></refpurpose>
+	    <refclass>Class</refclass>
+	  </refnamediv>
+
+	  <refsect1>
+	    <title>Superclasses</title>
+
+	    <para>NS:NS-STRING</para>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Initargs</title>
+	    =

+	    <variablelist>
+	      <varlistentry>
+		<term>:string</term>
+		=

+		<listitem>
+		  <para>
+		    a Lisp string which is to be the content of
+		    the newly-created ns-lisp-string.
+		  </para>
+		</listitem>
+	      </varlistentry>
+	    </variablelist>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Description</title>
+
+	    <para>
+	      This class
+	      implements the interface of an NSString, which means that it can
+	      be passed to any Cocoa or Core Foundation function which expects
+	      one.
+	    </para>
+
+	    <para>
+	      The string itself is stored on the Lisp heap, which
+	      means that its memory management is automatic.  However, the
+	      ns-lisp-string object itself is a foreign
+	      object (that is, it has an objc metaclass), and resides on the
+	      foreign heap.  Therefore, it is necessary to explicitly free
+	      it, by sending a dealloc message.
+	    </para>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Examples</title>
+
+	    <para>
+	      You can create an ns-lisp-string with
+	      <function>make-instance</function>, just like
+	      any normal Lisp class:
+	    </para>
+
+	    <programlisting format=3D"linespecific"
+>? (defvar *the-string*
           (make-instance 'ccl::ns-lisp-string
-                         :string "Hello, Cocoa."))
-</programlisting>
-        <para>When you are done with the string, you must explicitly
-deallocate it:</para>
-        <programlisting>
-? (ccl::send *the-string* 'dealloc)
-</programlisting>
-        <para>You may wish to use an <literal>unwind-protect</literal>
-form to ensure that this happens:</para>
-        <programlisting>
-(let (*the-string*)
+                         :string "Hello, Cocoa."))</programlisting>
+	    =

+	    <para>
+	      When you are done with the string, you must explicitly
+	      deallocate it:
+	    </para>
+
+	    <programlisting format=3D"linespecific">? (ccl::send *the-string* 'de=
alloc)</programlisting>
+
+	    <para>
+	      You may wish to use an <function>unwind-protect</function>
+	      form to ensure that this happens:
+	    </para>
+
+	    <programlisting format=3D"linespecific"
+>(let (*the-string*)
   (unwind-protect (progn (setq *the-string*
                                (make-instance 'ccl::ns-lisp-string
                                               :string "Hello, Cocoa."))
                          (format t "~&amp;The string is ~D characters long=
.~%"
                                  (ccl::send *the-string* 'length)))
     (when *the-string*
-      (ccl::send *the-string* 'dealloc))))
-</programlisting>
-        <bridgehead renderas=3D"sect3">Notes</bridgehead>
-        <para>Currently, ns-lisp-string is defined in
-the file ccl/examples/cocoa-backtrace.lisp, which is a
-rather awkward place.  It was probably not originally meant
-as a public utility at all.  It would be good if it were
-moved someplace else.  Use at your own risk.</para>
-      </sect2>
+      (ccl::send *the-string* 'dealloc))))</programlisting>
+	  </refsect1>
+
+	  <refsect1>
+	    <title>Notes</title>
+
+	    <para>
+	      Currently, ns-lisp-string is defined in
+	      the file ccl/examples/cocoa-backtrace.lisp, which is a
+	      rather awkward place.  It was probably not originally meant
+	      as a public utility at all.  It would be good if it were
+	      moved someplace else.  Use at your own risk.
+	    </para>
+	  </refsect1>
+	</refentry>
     </sect1>
   </chapter>
 =

   <chapter id=3D"Understanding-and-Configuring-the-Garbage-Collector">
-    <para>Understanding and Configuring the Garbage Collector</para>
+    <title>Understanding and Configuring the Garbage Collector</title>
 =

     <sect1 id=3D"Heap-space-allocation">
-      <para>Heap space allocation
-Release 0.10 or later of OpenMCL uses a different memory management
-scheme than previous versions did. Those earlier versions would allocate a
-block of memory (of specified size) at startup and would allocate lisp
-objects within that block. When that block filled with live (non-GCed)
-objects, the lisp would signal a "heap full" condition. The heap
-size imposed a limit on the size of the largest object that could be
-allocated.</para>
-      <para>The new strategy involves reserving a very large (2GB on Darwi=
nPPC32,
-1GB on LinuxPPC, "very large" on 64-bit implementations) block at
-startup and consuming (and relinquishing) its contents as the size of
-the live lisp heap data grows and shrinks. After the initial heap image
-loads and after each full GC, the lisp kernel will try to ensure that a
-specified amount (the "lisp-heap-gc-threshold") of free memory is
-available. The inital value of this kernel variable is 16MB on 32-bit
-implementations and 32MB on 64-bit implementations ; it can be
-manipulated from Lisp (see below.)</para>
-      <para>The large reserved memory block consumes very little in the wa=
y of
-system resources; memory that's actually committed to the lisp heap
-(live data and the "threshold" area where allocation takes place)
-consumes finite resources (physical memory and swap space). The lisp's
-consumption of those resources is proportional to its actual memory usage,
-which is generally a good thing.</para>
-      <para>This scheme is much more flexible than the old one, but it may=
 also
-increase the possibility that those resources can become exhausted.
-Neither the new scheme nor the old handles that situation gracefully;
-under the old scheme, a program that consumes lots of memory may have run
-into an artificial limit on heap size before exhausting virtual memory.</p=
ara>
-      <para>The -R or &ndash;heap-reserve command-line option can be use t=
o limit the
-size of the reserved block and therefore bound heap expansion. Running</pa=
ra>
+      <title>Heap space allocation</title>
+      <para>Release 0.10 or later of OpenMCL uses a different memory
+      management scheme than previous versions did. Those earlier
+      versions would allocate a block of memory (of specified size) at
+      startup and would allocate lisp objects within that block. When
+      that block filled with live (non-GCed) objects, the lisp would
+      signal a "heap full" condition. The heap size imposed a limit on
+      the size of the largest object that could be allocated.</para>
+      <para>The new strategy involves reserving a very large (2GB on
+      DarwinPPC32, 1GB on LinuxPPC, "very large" on 64-bit
+      implementations) block at startup and consuming (and
+      relinquishing) its contents as the size of the live lisp heap
+      data grows and shrinks. After the initial heap image loads and
+      after each full GC, the lisp kernel will try to ensure that a
+      specified amount (the "lisp-heap-gc-threshold") of free memory
+      is available. The inital value of this kernel variable is 16MB
+      on 32-bit implementations and 32MB on 64-bit implementations ;
+      it can be manipulated from Lisp (see below.)</para>
+      <para>The large reserved memory block consumes very little in
+      the way of system resources; memory that's actually committed to
+      the lisp heap (live data and the "threshold" area where
+      allocation takes place) consumes finite resources (physical
+      memory and swap space). The lisp's consumption of those
+      resources is proportional to its actual memory usage, which is
+      generally a good thing.</para>
+      <para>This scheme is much more flexible than the old one, but it
+      may also increase the possibility that those resources can
+      become exhausted.  Neither the new scheme nor the old handles
+      that situation gracefully; under the old scheme, a program that
+      consumes lots of memory may have run into an artificial limit on
+      heap size before exhausting virtual memory.</para> =

+
+      <para>The -R or &ndash;heap-reserve command-line option can be
+      use to limit the size of the reserved block and therefore bound
+      heap expansion. Running</para>
       <programlisting>
 > openmcl --heap-reserve 8M
 </programlisting>
@@ -9369,478 +13149,686 @@
     </sect1>
 =

     <sect1 id=3D"The-Ephemeral-GC">
-      <para>The Ephemeral GC
-For many programs, the following observations are true to a very
-large degree:</para>
-      <varlistentry numeration=3D"arabic">
-        <variablelist>Most heap-allocated objects have very short lifetime=
s ("areephemeral"): they become inaccessible soon after they're created.</v=
ariablelist>
-        <variablelist>Most non-ephemeral objects have very long lifetimes:=
 it'srarely productive for the GC to consider reclaiming them, sinceit's ra=
rely able to do so. (An object that's survived a largenumber of GCs is like=
ly to survive the next one. That's not alwaystrue of course, but it's a rea=
sonable heuristic.)</variablelist>
-        <variablelist>It's relatively rare for an old object to be destruc=
tivelymodified (via SETF) so that it points to a new one, therefore mostref=
erences to newly-created objects can be found in the stacks andregisters of=
 active threads. It's not generally necessary to scanthe entire heap to fin=
d references to new objects (or to prove thatsuch references don't exists),=
 though it is necessary to keeptrack of the (hopefully exceptional) cases w=
here old objects aremodified to point at new ones.</variablelist>
-      </varlistentry>
-      <para>"Ephemeral" (or "generational") garbage collectors try to expl=
oit
-these observations: by concentrating on frequently reclaiming
-newly-created objects quickly, it's less often necessary to do more
-expensive GCs of the entire heap in order to reclaim unreferenced memory.
-In some environments, the pauses associated with such full GCs can be
-noticable and disruptive, and minimizing the frequency (and sometimes the
-duration) of these pauses is probably the EGC's primary goal (though
-there may be other benefits, such as increased locality of reference and
-better paging behavior.) The EGC generally leads to slightly longer
-execution times (and slightly higher, amortized GC time), but there are
-cases where it can improve overall performance as well; the nature and
-degree of its impact on performance is highly application-dependant.</para>
-      <para>Most EGC strategies (including the one employed by OpenMCL)
-logically or physically divide memory into one or more areas of relatively
-young objects ("generations") and one or more areas of old objects.
-Objects that have survived one or more GCs as members of a young
-generation are promoted (or "tenured") into an older generation, where
-they may or may not survive long enough to be promoted to the next
-generation and eventually may become "old" objects that can only be
-reclaimed if a full GC proves that there are no live references to them.
-This filtering process isn't perfect - a certain amount of premature
-tenuring may take place - but it usually works very well in practive.</par=
a>
-      <para>It's important to note that a GC of the youngest generation is
-typically very fast (perhaps a few milliseconds on a modern CPU, depending
-on various factors), OpenMCL's EGC is not concurrent and doesn't
-offer realtime guarantees.</para>
-      <para>OpenMCL's EGC maintains three ephemeral
-generations; all newly created objects are created as members of the
-youngest generation. Each generation has an associated
-<emphasis>threshold</emphasis>, which indicates the number of bytes in it
-and all younger generations that can be allocated before a GC is
-triggered. These GCs will involve the target generation and all younger
-ones (and may therefore cause some premature tenuring); since the older
-generations have larger thresholds, they're GCed less frequently and
-most short-lived objects that make it into an older generation tend not to
-survive there very long.</para>
-      <para>The EGC can be <emphasis>enabled</emphasis> or <emphasis>disab=
led</emphasis>
-under program control; under some circumstances, it may be enabled but
-<emphasis>inactive</emphasis> (because a full GC is imminent.) Since it
-may be hard to know or predict the consing behavior of other threads, the
-distinction between the "active" and "inactive" state isn't very
-meaningful, especially when native threads are involved.</para>
+      <title>The Ephemeral GC</title>
+      <para>For many programs, the following observations are true to
+      a very large degree:</para>
+
+      <orderedlist continuation=3D"restarts" inheritnum=3D"ignore">
+	<listitem>
+	  <para>Most heap-allocated objects have very short lifetimes ("are
+	  ephemeral"): they become inaccessible soon after they&#39;re created.</=
para>
+	</listitem>
+
+	<listitem>
+	  <para>Most non-ephemeral objects have very long lifetimes: it&#39;s
+	  rarely productive for the GC to consider reclaiming them, since
+	  it&#39;s rarely able to do so. (An object that&#39;s survived a large
+	  number of GCs is likely to survive the next one. That&#39;s not always
+	  true of course, but it&#39;s a reasonable heuristic.)</para>
+	</listitem>
+
+	<listitem>
+	  <para>It&#39;s relatively rare for an old object to be destructively
+	  modified (via SETF) so that it points to a new one, therefore most
+	  references to newly-created objects can be found in the stacks and
+	  registers of active threads. It&#39;s not generally necessary to scan
+	  the entire heap to find references to new objects (or to prove that
+	  such references don&#39;t exists), though it is necessary to keep
+	  track of the (hopefully exceptional) cases where old objects are
+	  modified to point at new ones.</para>
+	</listitem>
+      </orderedlist>
+      <orderedlist continuation=3D"restarts" inheritnum=3D"ignore">
+	<listitem>
+	  <para>Most heap-allocated objects have very short lifetimes ("are
+	  ephemeral"): they become inaccessible soon after they&#39;re created.</=
para>
+	</listitem>
+
+	<listitem>
+	  <para>Most non-ephemeral objects have very long lifetimes: it&#39;s
+	  rarely productive for the GC to consider reclaiming them, since
+	  it&#39;s rarely able to do so. (An object that&#39;s survived a large
+	  number of GCs is likely to survive the next one. That&#39;s not always
+	  true of course, but it&#39;s a reasonable heuristic.)</para>
+	</listitem>
+
+	<listitem>
+	  <para>It&#39;s relatively rare for an old object to be destructively
+	  modified (via SETF) so that it points to a new one, therefore most
+	  references to newly-created objects can be found in the stacks and
+	  registers of active threads. It&#39;s not generally necessary to scan
+	  the entire heap to find references to new objects (or to prove that
+	  such references don&#39;t exists), though it is necessary to keep
+	  track of the (hopefully exceptional) cases where old objects are
+	  modified to point at new ones.</para>
+	</listitem>
+      </orderedlist>
+
+      <para>"Ephemeral" (or "generational") garbage collectors try to
+      exploit these observations: by concentrating on frequently
+      reclaiming newly-created objects quickly, it's less often
+      necessary to do more expensive GCs of the entire heap in order
+      to reclaim unreferenced memory.  In some environments, the
+      pauses associated with such full GCs can be noticable and
+      disruptive, and minimizing the frequency (and sometimes the
+      duration) of these pauses is probably the EGC's primary goal
+      (though there may be other benefits, such as increased locality
+      of reference and better paging behavior.) The EGC generally
+      leads to slightly longer execution times (and slightly higher,
+      amortized GC time), but there are cases where it can improve
+      overall performance as well; the nature and degree of its impact
+      on performance is highly application-dependant.</para>
+      <para>Most EGC strategies (including the one employed by
+      OpenMCL) logically or physically divide memory into one or more
+      areas of relatively young objects ("generations") and one or
+      more areas of old objects.  Objects that have survived one or
+      more GCs as members of a young generation are promoted (or
+      "tenured") into an older generation, where they may or may not
+      survive long enough to be promoted to the next generation and
+      eventually may become "old" objects that can only be reclaimed
+      if a full GC proves that there are no live references to them.
+      This filtering process isn't perfect - a certain amount of
+      premature tenuring may take place - but it usually works very
+      well in practive.</para>
+      <para>It's important to note that a GC of the youngest
+      generation is typically very fast (perhaps a few milliseconds on
+      a modern CPU, depending on various factors), OpenMCL's EGC is
+      not concurrent and doesn't offer realtime guarantees.</para>
+      <para>OpenMCL's EGC maintains three ephemeral generations; all
+      newly created objects are created as members of the youngest
+      generation. Each generation has an associated
+      <emphasis>threshold</emphasis>, which indicates the number of
+      bytes in it and all younger generations that can be allocated
+      before a GC is triggered. These GCs will involve the target
+      generation and all younger ones (and may therefore cause some
+      premature tenuring); since the older generations have larger
+      thresholds, they're GCed less frequently and most short-lived
+      objects that make it into an older generation tend not to
+      survive there very long.</para>
+      <para>The EGC can be <emphasis>enabled</emphasis> or
+      <emphasis>disabled</emphasis> under program control; under some
+      circumstances, it may be enabled but
+      <emphasis>inactive</emphasis> (because a full GC is imminent.)
+      Since it may be hard to know or predict the consing behavior of
+      other threads, the distinction between the "active" and
+      "inactive" state isn't very meaningful, especially when native
+      threads are involved.</para>
     </sect1>
 =

     <sect1 id=3D"GC-Page-reclamation-policy">
-      <para>GC Page reclamation policy</para>
-      <para>After a full GC finishes, it'll try to ensure that at least
-(LISP-HEAP-GC-THRESHOLD) of virtual memory are available; objects will be
-allocated in this block of memory until it fills up, the GC is triggered,
-and the process repeats itself.</para>
-      <para>Many programs reach near stasis in terms of the amount of logi=
cal
-memory that's in use after full GC (or run for long periods of time in
-a nearly static state), so the logical address range used for consing
-after the Nth full GC is likely to be nearly or entirely identical to the
-address range used by the N+1th full GC.</para>
-      <para>By default (and traditionally in OpenMCL), the GC's policy is =
to
-"release" the pages in this address range: to advise the virtual memory
-system that the pages contain garbage and any physical pages associated
-with them don't need to be swapped out to disk before being reused and
-to (re-)map the logical address range so that the pages will be
-zero-filled by the virtual memory system when they're next accessed.
-This policy is intended to reduce the load on the VM system and keep
-OpenMCL's working set to a minimum.</para>
-      <para>For some programs (especially those that cons at a very high r=
ate),
-the default policy may be less than ideal: releasing pages that're
-going to be needed almost immediately - and zero-fill-faulting them back
-in, lazily - incurs unnecessary overhead. (There's a false economy
-associated with minimizing the size of the working set if it's just
-going to shoot back up again until the next GC.) A policy of "retaining"
-pages between GCs might work better in such an environment.</para>
-      <para>Functions described below give the user some control over this
-behavior. An adaptive, feedback-mediated approach might yield a better
-solution.</para>
+      <title>GC Page reclamation policy</title>
+      <para>After a full GC finishes, it'll try to ensure that at
+      least (LISP-HEAP-GC-THRESHOLD) of virtual memory are available;
+      objects will be allocated in this block of memory until it fills
+      up, the GC is triggered, and the process repeats itself.</para>
+      <para>Many programs reach near stasis in terms of the amount of
+      logical memory that's in use after full GC (or run for long
+      periods of time in a nearly static state), so the logical
+      address range used for consing after the Nth full GC is likely
+      to be nearly or entirely identical to the address range used by
+      the N+1th full GC.</para>
+      <para>By default (and traditionally in OpenMCL), the GC's policy
+      is to "release" the pages in this address range: to advise the
+      virtual memory system that the pages contain garbage and any
+      physical pages associated with them don't need to be swapped out
+      to disk before being reused and to (re-)map the logical address
+      range so that the pages will be zero-filled by the virtual
+      memory system when they're next accessed.  This policy is
+      intended to reduce the load on the VM system and keep OpenMCL's
+      working set to a minimum.</para>
+      <para>For some programs (especially those that cons at a very
+      high rate), the default policy may be less than ideal: releasing
+      pages that're going to be needed almost immediately - and
+      zero-fill-faulting them back in, lazily - incurs unnecessary
+      overhead. (There's a false economy associated with minimizing
+      the size of the working set if it's just going to shoot back up
+      again until the next GC.) A policy of "retaining" pages between
+      GCs might work better in such an environment.</para>
+      <para>Functions described below give the user some control over
+      this behavior. An adaptive, feedback-mediated approach might
+      yield a better solution.</para>
     </sect1>
 =

     <sect1 id=3D"iPure--areas-are-read-only--paged-from-image-file">
-      <para>"Pure" areas are read-only, paged from image file
-SAVE-APPLICATION identifies code vectors and the pnames of interned
-symbols and copies these objects to a "pure" area of the image
-file it creates. (The "pure" area accounts for most of what the
-ROOM function reports as "static" space.)</para>
-      <para>When the resulting image file is loaded, the pure area of the =
file
-is now memory-mapped with read-only access. Code and pure data are paged
-in from the image file as needed (and don't compete for global virtual
-memory resources with other memory areas.)</para>
-      <para>Code-vectors and interned symbol pnames are immutable : it is =
an
-error to try to change the contents of such an object. Previously, that
-error would have manifested itself in some random way. In the new scheme,
-it'll manifest itself as an "unhandled exception" error in the
-Lisp kernel. The kernel could probably be made to detect a spurious,
-accidental write to read-only space and signal a lisp error in that case,
-but it doesn't yet do so.</para>
-      <para>The image file should be opened and/or mapped in some mode whi=
ch
-disallows writing to the memory-mapped regions of the file from other
-processes. I'm not sure of how to do that; writing to the file when
-it's mapped by OpenMCL can have unpredictable and unpleasant results.
-SAVE-APPLICATION will delete its output file's directory entry and
-create a new file; one may need to exercise care when using file system
-utilities (like tar, for instance) that might overwrite an existing image
-file.</para>
+      <title>"Pure" areas are read-only, paged from image file</title>
+      <para>SAVE-APPLICATION identifies code vectors and the pnames of
+      interned symbols and copies these objects to a "pure" area of
+      the image file it creates. (The "pure" area accounts for most of
+      what the ROOM function reports as "static" space.)</para>
+      <para>When the resulting image file is loaded, the pure area of
+      the file is now memory-mapped with read-only access. Code and
+      pure data are paged in from the image file as needed (and don't
+      compete for global virtual memory resources with other memory
+      areas.)</para>
+      <para>Code-vectors and interned symbol pnames are immutable : it
+      is an error to try to change the contents of such an
+      object. Previously, that error would have manifested itself in
+      some random way. In the new scheme, it'll manifest itself as an
+      "unhandled exception" error in the Lisp kernel. The kernel could
+      probably be made to detect a spurious, accidental write to
+      read-only space and signal a lisp error in that case, but it
+      doesn't yet do so.</para>
+      <para>The image file should be opened and/or mapped in some mode
+      which disallows writing to the memory-mapped regions of the file
+      from other processes. I'm not sure of how to do that; writing to
+      the file when it's mapped by OpenMCL can have unpredictable and
+      unpleasant results.  SAVE-APPLICATION will delete its output
+      file's directory entry and create a new file; one may need to
+      exercise care when using file system utilities (like tar, for
+      instance) that might overwrite an existing image file.</para>
     </sect1>
 =

     <sect1 id=3D"Weak-Hash-Tables">
-      <para>Weak Hash Tables
-In general, a "weak reference" is a reference to an object which
-will not prevent the object from being garbage-collected.  For
-example, suppose that you want to keep a list of all the objects
-of a certain type.  If you don't take special steps, the fact that
-you have a list of them will mean that the objects are always
-"live", because you can always reference them through the list.
-Therefore, they will never be garbage-collected, and their memory
-will never be reclaimed, even if they are referenced nowhere else
-in the program.  You may want this behaviour.  If you don't, you
-need weak references.</para>
+      <title>Weak Hash Tables</title>
+      <para>In general, a "weak reference" is a reference to an object
+      which will not prevent the object from being garbage-collected.
+      For example, suppose that you want to keep a list of all the
+      objects of a certain type.  If you don't take special steps, the
+      fact that you have a list of them will mean that the objects are
+      always "live", because you can always reference them through the
+      list.  Therefore, they will never be garbage-collected, and
+      their memory will never be reclaimed, even if they are
+      referenced nowhere else in the program.  You may want this
+      behaviour.  If you don't, you need weak references.</para>
       <para>OpenMCL supports weak references with "weak hash tables".
-Hash tables may be weak with respect to either their keys or
-their values.  To make a hash table with weak keys, invoke
-<literal>make-hash-table</literal> with the option :weak t,
-or, equivalently, :weak :key.  To make one with weak values,
-use :weak :value.  When the key is weak, the equality test
-must be #'eq (because it wouldn't make sense otherwise).</para>
-      <para>When garbage-collection occurs, key-value pairs are removed
-from the hash table if there are no other references to the
-weak element of the pair (key or value).</para>
-      <para>In general, weak-key hash tables are useful when you want to
-use the hash to store some extra information about the objects
-you look up in it, while weak-value hash tables are useful when you
-want to use the hash as an index for looking up objects.</para>
-      <para>If you are experimenting with weak hash tables interactively, =
remember
-that an object is not dead if it was returned by one of the last
-three interactively-evaluated expressions, because of the variables
-<literal>*</literal>, <literal>**</literal>, and
-<literal>***</literal>.  The easy workaround is to evaluate some
-meaningless expression before invoking <literal>gc</literal>,
-to get the object out of the repl variables.</para>
+      Hash tables may be weak with respect to either their keys or
+      their values.  To make a hash table with weak keys, invoke
+      <literal>make-hash-table</literal> with the option :weak t, or,
+      equivalently, :weak :key.  To make one with weak values, use
+      :weak :value.  When the key is weak, the equality test must be
+      #'eq (because it wouldn't make sense otherwise).</para>
+      <para>When garbage-collection occurs, key-value pairs are
+      removed from the hash table if there are no other references to
+      the weak element of the pair (key or value).</para>
+      <para>In general, weak-key hash tables are useful when you want
+      to use the hash to store some extra information about the
+      objects you look up in it, while weak-value hash tables are
+      useful when you want to use the hash as an index for looking up
+      objects.</para>
+      <para>If you are experimenting with weak hash tables
+      interactively, remember that an object is not dead if it was
+      returned by one of the last three interactively-evaluated
+      expressions, because of the variables <literal>*</literal>,
+      <literal>**</literal>, and <literal>***</literal>.  The easy
+      workaround is to evaluate some meaningless expression before
+      invoking <literal>gc</literal>, to get the object out of the
+      repl variables.</para>
     </sect1>
 =

     <sect1 id=3D"Garbage-Collection-Dictionary">
-      <para>Garbage-Collection Dictionary</para>
-
-      <sect2 id=3D"LISP-HEAP-GC-THRESHOLD">
-        <para>LISP-HEAP-GC-THRESHOLD</para>
-        <informalfigure>lisp-heap-gc-threshold</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>LISP-HEAP-GC-THRESHOLD &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-lisp-heap-gc-threshold
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns the value of the kernel variable that specifies the
-amount of free space to leave in the heap after full GC.</para>
-      </sect2>
-
-      <sect2 id=3D"SET-LISP-HEAP-GC-THRESHOLD">
-        <para>SET-LISP-HEAP-GC-THRESHOLD</para>
-        <informalfigure>set-lisp-heap-gc-threshold</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SET-LISP-HEAP-GC-THRESHOLD &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    lisp-heap-gc-threshold new-threshold
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>new-value
-            <variablelist>The requested new lisp-heap-gc-threshold.</varia=
blelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Sets the value of the kernel variable that specifies the
-amount of free space to leave in the heap after full GC to
-new-value, which should be a non-negative fixnum. Returns the
-value of that kernel variable (which may be somewhat larger than
-what was specified).</para>
-      </sect2>
-
-      <sect2 id=3D"USE-LISP-HEAP-GC-THRESHOLD">
-        <para>USE-LISP-HEAP-GC-THRESHOLD</para>
-        <informalfigure>use-lisp-heap-gc-threshold</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>USE-LISP-HEAP-GC-THRESHOLD &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    use-lisp-heap-gc-threshold
-
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Tries to grow or shrink lisp's heap space, so that the
-free space is (approximately) equal to the current heap threshold.
-Returns NIL</para>
-      </sect2>
-
-      <sect2 id=3D"EGC">
-        <para>EGC</para>
-        <informalfigure>egc</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>EGC &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-egc arg
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>arg
-            <variablelist>a generalized boolean</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Enables the EGC if arg is non-nil, disables the EGC
-otherwise. Returns the previous enabled status. Although this
-function is thread-safe (in the sense that calls to it are
-serialized), it doesn't make a whole lot of sense to be
-turning the EGC on and off from multiple threads ...</para>
-      </sect2>
-
-      <sect2 id=3D"EGC-ENABLED-P">
-        <para>EGC-ENABLED-P</para>
-        <informalfigure>egc-enabled-p</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>EGC-ENABLED-P &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-egc-enabled-p
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns T if the EGC was enabled at the time of the call,
-NIL otherwise.</para>
-      </sect2>
-
-      <sect2 id=3D"EGC-ACTIVE-P">
-        <para>EGC-ACTIVE-P</para>
-        <informalfigure>egc-active-p</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>EGC-ACTIVE-P &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-egc-active-p
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns T if the EGC was active at the time of the call, NIL
-otherwise. Since this is generally a volatile piece of
-information, it's not clear whether this function serves a
-useful purpose when native threads are involved.</para>
-      </sect2>
-
-      <sect2 id=3D"EGC-CONFIGURATION">
-        <para>EGC-CONFIGURATION</para>
-        <informalfigure>egc-configuration</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>EGC-CONFIGURATION &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-egc-configuration
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns, as multiple values, the sizes in kilobytes of the
-thresholds associated with the youngest ephemeral generation, the
-middle ephemeral generation, and the oldest ephemeral generation</para>
-      </sect2>
-
-      <sect2 id=3D"CONFIGURE-EGC">
-        <para>CONFIGURE-EGC</para>
-        <informalfigure>configure-egc</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>CONFIGURE-EGC &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-configure-egc
+      <title>Garbage-Collection Dictionary</title>
+
+      <refentry id=3D"f_lisp-heap-gc-threshold">
+	<indexterm zone=3D"f_lisp-heap-gc-threshold">
+	  <primary>lisp-heap-gc-threshold</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>LISP-HEAP-GC-THRESHOLD</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>lisp-heap-gc-threshold</function></synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns the value of the kernel variable that specifies the
+	  amount of free space to leave in the heap after full GC.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_set-lisp-heap-gc-threshold">
+	<indexterm zone=3D"f_set-lisp-heap-gc-threshold">
+	  <primary>set-lisp-heap-gc-threshold</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>SET-LISP-HEAP-GC-THRESHOLD</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>lisp-heap-gc-threshold new-threshold</function>
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>new-value</term>
+
+	      <listitem>
+		<para>The requested new lisp-heap-gc-threshold.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Sets the value of the kernel variable that specifies the
+	  amount of free space to leave in the heap after full GC to
+	  new-value, which should be a non-negative fixnum. Returns the
+	  value of that kernel variable (which may be somewhat larger than
+	  what was specified).</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_use-lisp-heap-gc-threshold">
+	<indexterm zone=3D"f_use-lisp-heap-gc-threshold">
+	  <primary>use-lisp-heap-gc-threshold</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>USE-LISP-HEAP-GC-THRESHOLD</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis>
+	    <function>use-lisp-heap-gc-threshold</function>
+	  </synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Tries to grow or shrink lisp&#39;s heap space, so that the
+	  free space is (approximately) equal to the current heap threshold.
+	  Returns NIL</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_egc">
+	<indexterm zone=3D"f_egc">
+	  <primary>egc</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>EGC</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>egc</function> arg</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>arg</term>
+
+	      <listitem>
+		<para>a generalized boolean</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Enables the EGC if arg is non-nil, disables the EGC
+	  otherwise. Returns the previous enabled status. Although this
+	  function is thread-safe (in the sense that calls to it are
+	  serialized), it doesn&#39;t make a whole lot of sense to be
+	  turning the EGC on and off from multiple threads ...</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_egc-enabled-p">
+	<indexterm zone=3D"f_egc-enabled-p">
+	  <primary>egc-enabled-p</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>EGC-ENABLED-P</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>egc-enabled-p</function></synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns T if the EGC was enabled at the time of the call,
+	  NIL otherwise.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_egc-active-p">
+	<indexterm zone=3D"f_egc-active-p">
+	  <primary>egc-active-p</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>EGC-ACTIVE-P</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>egc-active-p</function></synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns T if the EGC was active at the time of the call, NIL
+	  otherwise. Since this is generally a volatile piece of
+	  information, it&#39;s not clear whether this function serves a
+	  useful purpose when native threads are involved.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_egc-configuration">
+	<indexterm zone=3D"f_egc-configuration">
+	  <primary>egc-configuration</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>EGC-CONFIGURATION</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>egc-configuration</function></synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns, as multiple values, the sizes in kilobytes of the
+	  thresholds associated with the youngest ephemeral generation, the
+	  middle ephemeral generation, and the oldest ephemeral generation</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_configure-gcc">
+	<indexterm zone=3D"f_configure-gcc">
+	  <primary>configure-gcc</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CONFIGURE-GCC</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>configure-egc</function>
 	  generation-0-size generation-1-size
-	  generation-2-size
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>generation-0-size
-            <variablelist>the requested threshold size of the youngestgene=
ration, in kilobytes</variablelist>
-          </indexterm><indexterm>generation-1-size
-            <variablelist>the requested threshold size of the middle gener=
ation,in kilobytes</variablelist>
-          </indexterm><indexterm>generation-2-size
-            <variablelist>the requested threshold size of the oldest gener=
ation,in kilobytes</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>If the EGC is currently disabled, puts the indicated
-threshold sizes in effect and returns T, otherwise, returns NIL.
-(The provided threshold sizes are rounded up to a multiple of
-64Kbytes in OpenMCL 0.14 and later, and to a multiple of 32KBytes in earli=
er
-versions.)</para>
-      </sect2>
-
-      <sect2 id=3D"GC-RETAIN-PAGES">
-        <para>GC-RETAIN-PAGES</para>
-        <informalfigure>gc-retain-pages</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>GC-RETAIN-PAGES &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-gc-retain-pages arg
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>arg
-            <variablelist>a generalized boolean</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Tries to influence the GC to retain/recycle the pages
-allocated between GCs if arg is true, and to release them
-otherwise. This is generally a tradeoff between paging and other
-VM considerations.</para>
-      </sect2>
-
-      <sect2 id=3D"GC-RETAINING-PAGES">
-        <para>GC-RETAINING-PAGES</para>
-        <informalfigure>gc-retaining-pages</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>GC-RETAINING-PAGES &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-gc-retaining-pages
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns T if the GC tries to retain pages between full GCs
-and NIL if it's trying to release them to improve VM paging
-performance.</para>
-      </sect2>
+	  generation-2-size</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>generation-0-size</term>
+
+	      <listitem>
+		<para>the requested threshold size of the youngest
+		generation, in kilobytes</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>generation-1-size</term>
+
+	      <listitem>
+		<para>the requested threshold size of the middle generation,
+		in kilobytes</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>generation-2-size</term>
+
+	      <listitem>
+		<para>the requested threshold size of the oldest generation,
+		in kilobytes</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>If the EGC is currently disabled, puts the indicated
+	  threshold sizes in effect and returns T, otherwise, returns NIL.
+	  (The provided threshold sizes are rounded up to a multiple of
+	  64Kbytes in OpenMCL 0.14 and to a multiple of 32KBytes in earlier
+	  versions.)</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_gc-retain-pages">
+	<indexterm zone=3D"f_gc-retain-pages">
+	  <primary>gc-retain-pages</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>GC-RETAIN-PAGES</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>gc-retain-pages</function> arg</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>arg</term>
+
+	      <listitem>
+		<para>a generalized boolean</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Tries to influence the GC to retain/recycle the pages
+	  allocated between GCs if arg is true, and to release them
+	  otherwise. This is generally a tradeoff between paging and other
+	  VM considerations.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_gc-retaining-pages">
+	<indexterm zone=3D"f_gc-retaining-pages">
+	  <primary>gc-retaining-pages</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>GC-RETAINING-PAGES</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>gc-retaining-pages</function></synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns T if the GC tries to retain pages between full GCs
+	  and NIL if it&#39;s trying to release them to improve VM paging
+	  performance.</para>
+	</refsect1>
+      </refentry>
     </sect1>
   </chapter>
 =

   <chapter id=3D"Implementation-Details-of-OpenMCL">
-    <para>Implementation Details of OpenMCL
-This chapter describes many aspects of OpenMCL's implementation as of
-(roughly) version 1.1.  Details vary a bit between the three archutectures
-(PPC32, PPC64, and X86-64) currently supported and those details change
-over time, so the definitive reference is the source code (especially
-some files in the ccl/compiler/ directory whose names contain the string
-"arch" and some files in the ccl/lisp-kernel/ directory whose namee
-contain the string "constants".)  Hopefully, this chapter will make
-it easier for someone who's interested to read and understand the
-contents of those files.</para>
+    <title>Implementation Details of OpenMCL</title>
+    <para>This chapter describes many aspects of OpenMCL's
+    implementation as of (roughly) version 1.1.  Details vary a bit
+    between the three archutectures (PPC32, PPC64, and X86-64)
+    currently supported and those details change over time, so the
+    definitive reference is the source code (especially some files in
+    the ccl/compiler/ directory whose names contain the string "arch"
+    and some files in the ccl/lisp-kernel/ directory whose namee
+    contain the string "constants".)  Hopefully, this chapter will
+    make it easier for someone who's interested to read and understand
+    the contents of those files.</para>
 =

     <sect1 id=3D"Threads-and-exceptions">
-      <para>Threads and exceptions
-OpenMCL's threads are "native" (meaning that they're scheduled and
-controlled by the  operating system.)  Most of the implications of
-this are discussed elsewhere; this section tries to describe how
-threads look from the lisp kernel's perspective (and especailly
-from the GC's point of view.)</para>
-      <para>OpenMCL's runtime system tries to use machine-level exception
-mechanisms (conditional traps when available, illegal instructions,
-memory access protection in some cases) to detect and handle ...
-exceptional situations.  These situations include some TYPE-ERRORs
-and PROGRAM-ERRORS (notably wrong-number-of-args errors), and also
-include cases like "not being able to allocate memory without GCing
-or obtaining more memory from the OS."  The general idea is that
-it's usually faster to pay (very occasional) exception-processing
-overhead and figure out what's going on in an exception handler than
-it is to maintain enough state and context to handle an exceptional
-case via a lighter-weight mechanism when that exceptional case
-(by definition) rarely occurs.</para>
-      <para>Some emulated execution environments (the Rosetta PPC emulator=
 on
-x86 versions of OSX) don't provide accurate exception information
-to exception handling functions. OpenMCL can't run in such environments.</=
para>
+      <title>Threads and exceptions</title>
+      <para>OpenMCL's threads are "native" (meaning that they're
+      scheduled and controlled by the operating system.)  Most of the
+      implications of this are discussed elsewhere; this section tries
+      to describe how threads look from the lisp kernel's perspective
+      (and especailly from the GC's point of view.)</para>
+      <para>OpenMCL's runtime system tries to use machine-level
+      exception mechanisms (conditional traps when available, illegal
+      instructions, memory access protection in some cases) to detect
+      and handle ...  exceptional situations.  These situations
+      include some TYPE-ERRORs and PROGRAM-ERRORS (notably
+      wrong-number-of-args errors), and also include cases like "not
+      being able to allocate memory without GCing or obtaining more
+      memory from the OS."  The general idea is that it's usually
+      faster to pay (very occasional) exception-processing overhead
+      and figure out what's going on in an exception handler than it
+      is to maintain enough state and context to handle an exceptional
+      case via a lighter-weight mechanism when that exceptional case
+      (by definition) rarely occurs.</para>
+      <para>Some emulated execution environments (the Rosetta PPC
+      emulator on x86 versions of OSX) don't provide accurate
+      exception information to exception handling functions. OpenMCL
+      can't run in such environments.</para>
 =

       <sect2 id=3D"The-Thread-Context-Record">
-        <para>The Thread Context Record
-When a lisp thread is first created (or when a thread created by
-foreign code first calls back to lisp), a data structure called
-a Thread Context Record (or TCR) is allocated and initialized.  On
-modern versions of Linux and FreeBSD, the allocation actually happens
-via a set of thread-local-storage ABI extensions, so a thread's
-TCR is created when the thread is created and dies when the thread
-dies.  (The World's Most Advanced Operating System - as Apple's
-marketing literature refers to Darwin -  is not very advanced in this
-regard, and I know of no reason to assume that advances will be made
-in this area anytime soon.)</para>
-        <para>A TCR contains a few dozen fields (and is therefore a few hu=
ndred
-bytes in size.)  The fields are mostly thread-specific information
-about the thread's stacks' locations and sizes, information about
-the underlying (POSIX) thread, and information about the thread's
-dynamic binding history and pending CATCH/UNWIND-PROTECTs.  Some
-of this information could be kept in individual machine registers
-while the thread is running (and the PPC - which has more registers
-available - keeps a few things in registers that the X86-64 has
-to access via the TCR), but it's important to remember that the
-information is thread-specific and can't (for instance) be kept
-in a fixed global memory location.</para>
-        <para>When lisp code is running, the current thread's TCR is kept =
in
-a register.  On PPC platforms, a general purpose register is used;
-on x86-64, an (otherwise nearly useless) segment register works
-well (prevents the expenditure of a more generally useful general-
-purpose register for this purpose.)</para>
-        <para>The address of a TCR is aligned in memory in such a way that=
 a
-FIXNUM can be used to represent it.  The lisp function CCL::%CURRENT-TCR
-returns the calling thread's TCR as a fixnum; actual value of the
-TCR's address is 4 or 8 times the value of this fixnum.</para>
-        <para>When the lisp kernel initializes a new TCR, it's added to a =
global
-list maintained by the kernel; when a thread exits, its TCR is removed
-from this list.</para>
-        <para>When a thread calls foreign code, lisp stack pointers are sa=
ved in its
-TCR, lisp registers (at least those whose value should be preserved
-across the call) are saved on the thread's value stack, and (on x86-64)
-RSP is switched to the control stack.  A field in the TCR
-(tcr.valence) is then set to indicate that the thread is running foreigm
-code, foreign argument registers are loaded from a frame on the foreign
-stack, and the foreign function is called. (That's a little oversimplified
-and possibly inaccurate, but the important things to note are that the
-thread "stops following lisp stack and register usage conventions" and
-that it advertises the fact that it's done so.  Similar transitions in
-a thread's state ("valence") occur when it enters of exits an exception
-handler (which is sort of an OS/hardware-mandated foreign function call
-where the OS thoughtfully saves the thread's register state for it
-beforehand.)</para>
+	<title>The Thread Context Record</title>
+
+	<para>When a lisp thread is first created (or when a thread
+        created by foreign code first calls back to lisp), a data
+        structure called a Thread Context Record (or TCR) is allocated
+        and initialized.  On modern versions of Linux and FreeBSD, the
+        allocation actually happens via a set of thread-local-storage
+        ABI extensions, so a thread's TCR is created when the thread
+        is created and dies when the thread dies.  (The World's Most
+        Advanced Operating System - as Apple's marketing literature
+        refers to Darwin - is not very advanced in this regard, and I
+        know of no reason to assume that advances will be made in this
+        area anytime soon.)</para>
+        <para>A TCR contains a few dozen fields (and is therefore a
+        few hundred bytes in size.)  The fields are mostly
+        thread-specific information about the thread's stacks'
+        locations and sizes, information about the underlying (POSIX)
+        thread, and information about the thread's dynamic binding
+        history and pending CATCH/UNWIND-PROTECTs.  Some of this
+        information could be kept in individual machine registers
+        while the thread is running (and the PPC - which has more
+        registers available - keeps a few things in registers that the
+        X86-64 has to access via the TCR), but it's important to
+        remember that the information is thread-specific and can't
+        (for instance) be kept in a fixed global memory
+        location.</para>
+        <para>When lisp code is running, the current thread's TCR is
+        kept in a register.  On PPC platforms, a general purpose
+        register is used; on x86-64, an (otherwise nearly useless)
+        segment register works well (prevents the expenditure of a
+        more generally useful general- purpose register for this
+        purpose.)</para>
+        <para>The address of a TCR is aligned in memory in such a way
+        that a FIXNUM can be used to represent it.  The lisp function
+        CCL::%CURRENT-TCR returns the calling thread's TCR as a
+        fixnum; actual value of the TCR's address is 4 or 8 times the
+        value of this fixnum.</para>
+        <para>When the lisp kernel initializes a new TCR, it's added
+        to a global list maintained by the kernel; when a thread
+        exits, its TCR is removed from this list.</para>
+        <para>When a thread calls foreign code, lisp stack pointers
+        are saved in its TCR, lisp registers (at least those whose
+        value should be preserved across the call) are saved on the
+        thread's value stack, and (on x86-64) RSP is switched to the
+        control stack.  A field in the TCR (tcr.valence) is then set
+        to indicate that the thread is running foreigm code, foreign
+        argument registers are loaded from a frame on the foreign
+        stack, and the foreign function is called. (That's a little
+        oversimplified and possibly inaccurate, but the important
+        things to note are that the thread "stops following lisp stack
+        and register usage conventions" and that it advertises the
+        fact that it's done so.  Similar transitions in a thread's
+        state ("valence") occur when it enters of exits an exception
+        handler (which is sort of an OS/hardware-mandated foreign
+        function call where the OS thoughtfully saves the thread's
+        register state for it beforehand.)</para>
       </sect2>
 =

       <sect2 id=3D"Exception-contexts-comma---and-exception-handling-in-ge=
neral">
-        <para>Exception contexts, and exception-handling in general
-Unix-like OSes tend to refer to exceptions as "signals"; the same
-general mechanism ("signal handling") is used to process both
-asynchronous OS-level events (such as the result of the keyboard driver
-noticing that ^C or ^Z has been pressed) and synchronous hardware-level
-events (like trying to execute and illegal instruction or access
-protected memory.)  It makes some sense to defer ("block") handling
-of aysnchronous signals so that some critical code sequences complete
-without interruption; since it's generally not possible for a thread
-to proceed after a synchronous exception unless and until its state
-is modified by an exception handler, it makes no sense to talk about
-blocking synchronous signals (though some OSes will let you do so
-and doing so can have mysterious effects.)</para>
-        <para>On OSX/Darwin, the POSIX signal handling facilities coexist =
with
-lower-level Mach-based exception handling facilities.  Unfortunately,
-the way that this is implemented interacts poorly with debugging
-tools: GDB will generally stop whenever the target program
-encounters a Mach-level exception and offers no way to proceed from
-that point (and let the program's POSIX signal handler try to handle
-the exception); Apple's CrashReporter program has had a similar issue
-and, depending on how it's configured, may bombard the user with
-alert dialogs which falsely claim that an application has crashed
-(when in fact the application in question has routinely handled
-a routine exception.)  On Darwin/OSX, OpenMCL uses Mach thread-level
-exception handling facilities which run before GDB or CrashReporter
-get a chance to confuse themeselves; OpenMCL's Mach exception handling
-tries to force the thread which received a synchronous exception to
-invoke a signal handling function ("as if" signal handling worked
-more usefully under Darwin.)  Mach exception handlers run in a dedicated
-thread (which basically does nothing but wait for exception messages
-from the lisp kernel, obtain and modify information about the state
-of threads in which exceptions have occurred, and reply to the
-exception messages with an indication that the exception has been
-handled.  The reply from a thread-level exception handler keeps the
-exception from being reported to GDB or CrashReporter and avoids
-the problems related to those programs.  Since OpenMCL's Mach exception
-handler doesn't claim to handle debugging-related exceptions (from
-breakpoints or single-step operations), it's possible to use GDB to
-debug OpenMCL.</para>
+	<title>Exception contexts, and exception-handling in general</title>
+        <para>Unix-like OSes tend to refer to exceptions as "signals";
+        the same general mechanism ("signal handling") is used to
+        process both asynchronous OS-level events (such as the result
+        of the keyboard driver noticing that ^C or ^Z has been
+        pressed) and synchronous hardware-level events (like trying to
+        execute and illegal instruction or access protected memory.)
+        It makes some sense to defer ("block") handling of
+        aysnchronous signals so that some critical code sequences
+        complete without interruption; since it's generally not
+        possible for a thread to proceed after a synchronous exception
+        unless and until its state is modified by an exception
+        handler, it makes no sense to talk about blocking synchronous
+        signals (though some OSes will let you do so and doing so can
+        have mysterious effects.)</para>
+        <para>On OSX/Darwin, the POSIX signal handling facilities
+        coexist with lower-level Mach-based exception handling
+        facilities.  Unfortunately, the way that this is implemented
+        interacts poorly with debugging tools: GDB will generally stop
+        whenever the target program encounters a Mach-level exception
+        and offers no way to proceed from that point (and let the
+        program's POSIX signal handler try to handle the exception);
+        Apple's CrashReporter program has had a similar issue and,
+        depending on how it's configured, may bombard the user with
+        alert dialogs which falsely claim that an application has
+        crashed (when in fact the application in question has
+        routinely handled a routine exception.)  On Darwin/OSX,
+        OpenMCL uses Mach thread-level exception handling facilities
+        which run before GDB or CrashReporter get a chance to confuse
+        themeselves; OpenMCL's Mach exception handling tries to force
+        the thread which received a synchronous exception to invoke a
+        signal handling function ("as if" signal handling worked more
+        usefully under Darwin.)  Mach exception handlers run in a
+        dedicated thread (which basically does nothing but wait for
+        exception messages from the lisp kernel, obtain and modify
+        information about the state of threads in which exceptions
+        have occurred, and reply to the exception messages with an
+        indication that the exception has been handled.  The reply
+        from a thread-level exception handler keeps the exception from
+        being reported to GDB or CrashReporter and avoids the problems
+        related to those programs.  Since OpenMCL's Mach exception
+        handler doesn't claim to handle debugging-related exceptions
+        (from breakpoints or single-step operations), it's possible to
+        use GDB to debug OpenMCL.</para>
         <para>On platforms where signal handling and debugging don't get i=
n each
 other's way, a signal handler is entered with all signals blocked.
 (This behavior is specified in the call to the sigaction() function
@@ -9858,92 +13846,113 @@
 field to indicate that the thread is now waiting to handle an
 exception, unblocks asynchronous signals, and waits for a global
 exception lock which serializes exception processing.</para>
-        <para>On Darwin, the Mach exception thread creates a signal contex=
t (and
-maybe a siginfo_t structure), stores the signal context in the
-thread's TCR, sets the TCR field wich describes the thread's state,
-and arranges that the thread resume execution at its signal handling
-function (with a signal handler, possibly NULL siginfo_t, and signal
-context as arguments.  When the thread resumes, it waits for the
-global exception lock.</para>
-        <para>On x86-64 platforms where signal handing can be used to hand=
le
-synchronous exceptions, there's an additional complication: the
-OS kernel ordinarily allocates the signal context and siginfo
-structures on the stack of the thread which received the signal;
-in practice, that means "wherever RSP is pointing."  OpenMCL's
- require that the
-thread's value stack - where RSP is usually pointing while lisp
-code is running - contain only "nodes" (properly tagged lisp
-objects), and scribbling a signal context all over the value
-stack would violate this requirement.  To maintain consistency,
-the sigaltstack() mechanism is used to cause the signal to be
-delivered on (and the signal context and siginfo to be allocated
-on) a special stack area (the last few pages of the thread's
-cntrol stack, in practice.  When the signal handler runs, it
-(carefully) copies the signal context and siginfo to the thread's
-control stack and makes RSP point into that stack before invoking
-the "real" signal handler.  (The effect of this hack is that the
-"real" signal handler always runs on the thread's control stack.)</para>
-        <para>Once the exception handler has obtained the global exception=
 lock,
-it uses the values of the signal number, siginfo_t, and signal context
-arguments to determine the (logical) cause of the exception.  Some
-exceptions may be caused by factors that should generate lisp errors
-or other serious conditions (stack overflow); if this is the case,
-the kernel code may release the global exception lock and call out
-to lisp code.  (The lisp code in question may need to repeat some
-of the exception decoding process; in particular, it needs to be
-able to interpret register values in the signal context that it
-receives as an argument.)</para>
-        <para>In some cases, the lisp kernel exception handler may not be
-able to recover from the exception (this is currently true of
-some types of memory-access fault and is also true of traps
-or illegal instructions that occur during foreign code execution.
-In such cases, the kernel exception handler reports the
-exception as "unhandled", and the kernel debugger is invoked.</para>
-        <para>If the kernel exception handler identifies the exception' ca=
use
-as being a transient out-of-memory condition (indicating that
-the current thread needs more memory to cons in), it tries to
-make that memory available.  In some cases, doing so involves
-invoking the GC.</para>
+        <para>On Darwin, the Mach exception thread creates a signal
+        context (and maybe a siginfo_t structure), stores the signal
+        context in the thread's TCR, sets the TCR field wich describes
+        the thread's state, and arranges that the thread resume
+        execution at its signal handling function (with a signal
+        handler, possibly NULL siginfo_t, and signal context as
+        arguments.  When the thread resumes, it waits for the global
+        exception lock.</para>
+        <para>On x86-64 platforms where signal handing can be used to
+        handle synchronous exceptions, there's an additional
+        complication: the OS kernel ordinarily allocates the signal
+        context and siginfo structures on the stack of the thread
+        which received the signal; in practice, that means "wherever
+        RSP is pointing."  OpenMCL's require that the thread's value
+        stack - where RSP is usually pointing while lisp code is
+        running - contain only "nodes" (properly tagged lisp objects),
+        and scribbling a signal context all over the value stack would
+        violate this requirement.  To maintain consistency, the
+        sigaltstack() mechanism is used to cause the signal to be
+        delivered on (and the signal context and siginfo to be
+        allocated on) a special stack area (the last few pages of the
+        thread's cntrol stack, in practice.  When the signal handler
+        runs, it (carefully) copies the signal context and siginfo to
+        the thread's control stack and makes RSP point into that stack
+        before invoking the "real" signal handler.  (The effect of
+        this hack is that the "real" signal handler always runs on the
+        thread's control stack.)</para>
+        <para>Once the exception handler has obtained the global
+        exception lock, it uses the values of the signal number,
+        siginfo_t, and signal context arguments to determine the
+        (logical) cause of the exception.  Some exceptions may be
+        caused by factors that should generate lisp errors or other
+        serious conditions (stack overflow); if this is the case, the
+        kernel code may release the global exception lock and call out
+        to lisp code.  (The lisp code in question may need to repeat
+        some of the exception decoding process; in particular, it
+        needs to be able to interpret register values in the signal
+        context that it receives as an argument.)</para>
+        <para>In some cases, the lisp kernel exception handler may not
+        be able to recover from the exception (this is currently true
+        of some types of memory-access fault and is also true of traps
+        or illegal instructions that occur during foreign code
+        execution.  In such cases, the kernel exception handler
+        reports the exception as "unhandled", and the kernel debugger
+        is invoked.</para>
+        <para>If the kernel exception handler identifies the
+        exception' cause as being a transient out-of-memory condition
+        (indicating that the current thread needs more memory to cons
+        in), it tries to make that memory available.  In some cases,
+        doing so involves invoking the GC.</para>
       </sect2>
 =

       <sect2 id=3D"Threads-comma---exceptions-comma---and-the-GC">
-        <para>Threads, exceptions, and the GC
-OpenMCL's GC is not concurrent: when the GC is invoked in response to an
-exception in a particular thread, all other lisp threads must stop until
-the GC's work is done.  The thread that triggered the GC iterates over
-the global TCR list, sending each other thread a distinguished "suspend"
-signal, then iterates over the list again, waiting for a per-thread
-semaphore that indicates that the thread has received the "suspend"
-signal and responded appropriatedly.  Once all other threads have
-acknowledged the request to suspend themselves, the GC thread can
-run the GC proper (after doing any necessary .)  Once
-the GC's completed its work, the thread that invoked the GC iterates
-over the global TCR list, raising a per-thread "resume" semaphore
-for each other thread.</para>
-        <para>The signal handler for the asynchronous "suspend" signal is =
entered
-with all asynchronous signals blocked.  It saves its signal-context
-argument in a TCR slot, raises the tcr's "suspend" semaphore, then
-waits on the TCR's "resume" semaphore.</para>
-        <para>The GC thread has access to the signal contexts of all TCRs =
(including
-its own) at the time when the thread received an exception or
-acknowledged a request to suspend itself.  This information (and
-information about stack areas in the TCR itself) allows the GC to
-identify the "stack locations and register contents" that are elements
-of the GC's root set.</para>
+	<title>Threads, exceptions, and the GC</title>
+        <para>OpenMCL's GC is not concurrent: when the GC is invoked
+        in response to an exception in a particular thread, all other
+        lisp threads must stop until the GC's work is done.  The
+        thread that triggered the GC iterates over the global TCR
+        list, sending each other thread a distinguished "suspend"
+        signal, then iterates over the list again, waiting for a
+        per-thread semaphore that indicates that the thread has
+        received the "suspend" signal and responded appropriatedly.
+        Once all other threads have acknowledged the request to
+        suspend themselves, the GC thread can run the GC proper (after
+        doing any necessary .)  Once the GC's completed its work, the
+        thread that invoked the GC iterates over the global TCR list,
+        raising a per-thread "resume" semaphore for each other
+        thread.</para>
+        <para>The signal handler for the asynchronous "suspend" signal
+        is entered with all asynchronous signals blocked.  It saves
+        its signal-context argument in a TCR slot, raises the tcr's
+        "suspend" semaphore, then waits on the TCR's "resume"
+        semaphore.</para>
+        <para>The GC thread has access to the signal contexts of all
+        TCRs (including its own) at the time when the thread received
+        an exception or acknowledged a request to suspend itself.
+        This information (and information about stack areas in the TCR
+        itself) allows the GC to identify the "stack locations and
+        register contents" that are elements of the GC's root
+        set.</para>
       </sect2>
 =

       <sect2 id=3D"PC-lusering">
-        <para>PC-luseringIt's not quite accurate to say that OpenMCL's com=
piler and runtime
-follow precise stack and register usage conventions at all times; there
-are a few exceptions:</para>
-        <listitem mark=3D"bullet">
-          <variablelist>On both PPC and x86-64 platforms, consing isn't fu=
lly atomic.It takes at least a few instructions to allocate an object in me=
mory(and slap a header on it if necesssary); if a thread is interrupted int=
he middle of that instruction sequence, the new object may or may nothave b=
een created or fully initialized at the point in time that theinterrupt occ=
urred.  (There are actually a few different states ofpartial initialization=
)</variablelist>
-          <variablelist>On the PPC, the common act of building a lisp cont=
rol stack frameinvolves allocating a four-word frame and storing three regi=
ster valuesinto that frame.  (The fourth word - the back pointer to the pre=
viousframe - is automatically set when the frame is allocated.)  The previo=
uscontents of those three words are unknown (there might have been aforeign=
 stack frame at the same address a few instructions earlier),so interruptin=
g a thread that's in the process of initializing aPPC control stack frame i=
sn't GC-safe.</variablelist>
-          <variablelist>There are similar problems with the initialization=
 of temp stackframes on the PPC.  (Allocation and initialization doesn't ha=
ppenatomically, and the newly allocated stack memory may have undefinedcont=
ents.)</variablelist>
-          <variablelist>'s write barrier has to be implemented atomically =
(i.e.,both an intergenerational store and the update of a correspondingrefe=
rence bit has to happen without interruption, or neither of theseevents can=
 happen.)</variablelist>
-          <variablelist>There are a few more similar cases.</variablelist>
+	<title>PC-lusering</title>
+        <para>It's not quite accurate to say that OpenMCL's compiler
+        and runtime follow precise stack and register usage
+        conventions at all times; there are a few exceptions:</para>
+
+	<itemizedlist>
+          <listitem>
+<para>On both PPC and x86-64 platforms, consing isn't fully atomic.It take=
s at least a few instructions to allocate an object in memory(and slap a he=
ader on it if necesssary); if a thread is interrupted inthe middle of that =
instruction sequence, the new object may or may nothave been created or ful=
ly initialized at the point in time that theinterrupt occurred.  (There are=
 actually a few different states ofpartial initialization)</para>
+</listitem>
+          <listitem>
+<para>On the PPC, the common act of building a lisp control stack frameinv=
olves allocating a four-word frame and storing three register valuesinto th=
at frame.  (The fourth word - the back pointer to the previousframe - is au=
tomatically set when the frame is allocated.)  The previouscontents of thos=
e three words are unknown (there might have been aforeign stack frame at th=
e same address a few instructions earlier),so interrupting a thread that's =
in the process of initializing aPPC control stack frame isn't GC-safe.</par=
a>
+</listitem>
+          <listitem>
+<para>There are similar problems with the initialization of temp stackfram=
es on the PPC.  (Allocation and initialization doesn't happenatomically, an=
d the newly allocated stack memory may have undefinedcontents.)</para>
+</listitem>
+          <listitem>
+<para>'s write barrier has to be implemented atomically (i.e.,both an inte=
rgenerational store and the update of a correspondingreference bit has to h=
appen without interruption, or neither of theseevents can happen.)</para>
+</listitem>
+          <listitem>
+<para>There are a few more similar cases.</para>
+</listitem>
         =

-        </listitem>
+        </itemizedlist>
+
         <para>Fortunately, the number of these non-atomic instruction sequ=
ences is
 small, and fortunately it's fairly easy for the interrupting thread
 to recognize when the interrupted thread is in the middle of such
@@ -9961,287 +13970,621 @@
     </sect1>
 =

     <sect1 id=3D"Register-usage-and-tagging">
-      <para>Register usage and tagging</para>
+      <title>Register usage and tagging</title>
 =

       <sect2 id=3D"Register-usage-and-tagging-overview">
-        <para>Register usage and tagging overview
-Regardless of other details of its implementation, a garbage
-collector's job is to partition the set of all heap-allocated
-lisp objects (CONSes, STRINGs, INSTANCEs, etc.) into two subsets.
-The first subset contains all objects that are transitively referenced
-from a small set of "root" objects (the contents of the stacks
-and registers of all active threads at the time the GC occurs
-and the values of some global variables.)  The second subset contains
-everything else: those lisp objects that are not transitively
-reachable from the roots are garbage, and the memory occupied
-by garbage objects can be reclaimed (since the GC has just proven
-that it's impossible to reference them.)</para>
-        <para>The set of live, reachable lisp objects basically form the n=
odes
-of a (usually large) graph, with edges from each node A to any other
-objects (nodes) that object A references.</para>
-        <para>Some nodes in this graph can never have outgoing edges: an a=
rray with a
-specialized numeric or character type usually represents its elements in
-some (possibly more compact) specialized way.  Some nodes may refer
-to lisp objects that are never allocated in memory (FIXNUMs, CHARACTERs,
-SINGLE-FLOATs on 64-bit platforms ..)  This latter class of objects
-are sometimes called "immediates", but that's a little confusing
-because the term "immediate" is sometimes used to refer to things
-that can never be part of the big connectivity graph (e.g., the "raw"
-bits that make up a floating-point value, foreign address, or
-numeric value that needs to be used - at least fleetingly - in
-compiled code.)</para>
-        <para>For the GC to be able to build the connectivity graph reliab=
ly, it's
-necessary for it to be able to reliably tell (a) whether or not a
-"potential root" - the contents of a machine register or stack location
-- is in fact a node and (b) for any node, whether it may have components
-that refer to other nodes.</para>
-        <para>There's no reliable way to answer the first question on stoc=
k hardware.
-(If everything was a node, as might be the case on specially microcoded
-"lisp machine" hardware, it wouldn't even need to be asked.)  Since
-there's no way to just look at a machine word (the contents of a machine
-register or stack location) and tell whether or not it's a node or just
-some random non-node value, we have to either adopt and enforce strict
-conventions on register and stack usage or tolerate ambiguity.</para>
-        <para>"Tolerating ambiguity" is an approach taken by some ("conser=
vative") GC
-schemes; by contrast, OpenMCL's GC is "precise", which in this case
-means that it believes that the contents of certain machine registers
-and stack locations are always nodes and that other registers and stack
-locations are never nodes and that these conventions are never violated
-by the compiler or runtime system.  The fact that threads are
-preemptively scheduled means that a GC could occur (because of activity
-in some other thread) on any instruction boundary, which in turn means
-that the compiler and runtime system must follow precise  at all times.</p=
ara>
-        <para>Once we've decided that a given machine word is a node, a  d=
escribes how the node's value and type are encoded in that
-machine word.</para>
-        <para>Most of this - so far - has discussed thigs from the GC's ve=
ry low-level
-perspective.  From a much higher point of view, lisp functions accept
-nodes as arguments, return nodes as values, and (usually) perform
-some operations on those arguments in order to produce those results.
-(In many cases, the operations in question involve raw non-node values.)
-Higher-level parts of the lisp type system (functions like TYPE-OF
-and CLASS-OF, etc.) depend on the .</para>
+	<title>Overview</title>
+	<para>Regardless of other details of its implementation, a
+	garbage collector's job is to partition the set of all
+	heap-allocated lisp objects (CONSes, STRINGs, INSTANCEs, etc.)
+	into two subsets.  The first subset contains all objects that
+	are transitively referenced from a small set of "root" objects
+	(the contents of the stacks and registers of all active
+	threads at the time the GC occurs and the values of some
+	global variables.)  The second subset contains everything
+	else: those lisp objects that are not transitively reachable
+	from the roots are garbage, and the memory occupied by garbage
+	objects can be reclaimed (since the GC has just proven that
+	it's impossible to reference them.)</para>
+        <para>The set of live, reachable lisp objects basically form
+        the nodes of a (usually large) graph, with edges from each
+        node A to any other objects (nodes) that object A
+        references.</para>
+        <para>Some nodes in this graph can never have outgoing edges:
+        an array with a specialized numeric or character type usually
+        represents its elements in some (possibly more compact)
+        specialized way.  Some nodes may refer to lisp objects that
+        are never allocated in memory (FIXNUMs, CHARACTERs,
+        SINGLE-FLOATs on 64-bit platforms ..)  This latter class of
+        objects are sometimes called "immediates", but that's a little
+        confusing because the term "immediate" is sometimes used to
+        refer to things that can never be part of the big connectivity
+        graph (e.g., the "raw" bits that make up a floating-point
+        value, foreign address, or numeric value that needs to be used
+        - at least fleetingly - in compiled code.)</para>
+        <para>For the GC to be able to build the connectivity graph
+        reliably, it's necessary for it to be able to reliably tell
+        (a) whether or not a "potential root" - the contents of a
+        machine register or stack location - is in fact a node and (b)
+        for any node, whether it may have components that refer to
+        other nodes.</para>
+        <para>There's no reliable way to answer the first question on
+        stock hardware.  (If everything was a node, as might be the
+        case on specially microcoded "lisp machine" hardware, it
+        wouldn't even need to be asked.)  Since there's no way to just
+        look at a machine word (the contents of a machine register or
+        stack location) and tell whether or not it's a node or just
+        some random non-node value, we have to either adopt and
+        enforce strict conventions on register and stack usage or
+        tolerate ambiguity.</para>
+        <para>"Tolerating ambiguity" is an approach taken by some
+        ("conservative") GC schemes; by contrast, OpenMCL's GC is
+        "precise", which in this case means that it believes that the
+        contents of certain machine registers and stack locations are
+        always nodes and that other registers and stack locations are
+        never nodes and that these conventions are never violated by
+        the compiler or runtime system.  The fact that threads are
+        preemptively scheduled means that a GC could occur (because of
+        activity in some other thread) on any instruction boundary,
+        which in turn means that the compiler and runtime system must
+        follow precise at all times.</para>
+        <para>Once we've decided that a given machine word is a node,
+        a describes how the node's value and type are encoded in that
+        machine word.</para>
+        <para>Most of this - so far - has discussed thigs from the
+        GC's very low-level perspective.  From a much higher point of
+        view, lisp functions accept nodes as arguments, return nodes
+        as values, and (usually) perform some operations on those
+        arguments in order to produce those results.  (In many cases,
+        the operations in question involve raw non-node values.)
+        Higher-level parts of the lisp type system (functions like
+        TYPE-OF and CLASS-OF, etc.) depend on the .</para>
       </sect2>
 =

       <sect2 id=3D"pc-locatives-on-the-PPC">
-        <para>pc-locatives on the PPC
-On the PPC, there's a third case (besides "node" and "immediate" values).
-As discussed below, a node that denotes a memory-allocated lisp object
-is a biased (tagged) pointer -to- that object; it's not generally possible
-to point -into- some composite (multi-element) object (such a pointer
-would not be a node, and the GC would have no way to update the pointer
-if it were to move the underlying object.)</para>
-        <para>Such a pointer ("into" the interior of a heap-allocated obje=
ct) is
-often called a <emphasis>locative</emphasis>; the cases where locatives ar=
e allowed
-in OpenMCL mostly involve the behavior of function call and return
-instructions.  (To be technicaly accurate, the other case also arises
-on x86-64, but that case isn't as user-visible.)</para>
-        <para>On the PowerPC (both PPC32 and PPC64), all machine instructi=
ons are
-32 bits wide and all instruction words are allocated on 32-bit boundaries.
-In PPC OpenMCL, a CODE-VECTOR is a specialized type of vector-like object;
-its elements are 32-bit PPC machine instructions.  A CODE-VECTOR is
-an attribute of FUNCTION object; a function call involves accessing the
-function's code-vector and jumping to the address of its first instruction=
.</para>
-        <para>As each instruction in the code vector sequentially executes=
, the
-hardware program counter (PC) register advances to the address of the
-next instruction (a locative into the code vector); since PPC
-instructions are always 32 bits wide and aligned on 32-bit boundaries,
-the low two bits of the PC are always 0.  If the function executes a
-call (simple call instrucions have the mnemonic "bl" on the PPC, which
-stands for "branch and link"), the address of the next instruction (also
-a word-aligned locative into a code-vector) is copied into the special-
-purpose PPC "link register" (lr); a function returns to its caller
-via a "branch to link register" (blr) instruction.  Some cases of
-function call and return might also use the PPC's "count register"
-(ctr), and if either the lr or ctr needs to be stored in memory it
-needs to first be copied to a general-purpose registers.</para>
-        <para>OpenMCL's GC understands that certain registers contain thes=
e special
-"pc-locatives" (locatives that point into CODE-VECTOR objects); it
-contains specal support for finding the containing CODE-VECTOR object
-and for adjusting all of these "pc-locatives" if the containing object
-is moved in memory.  The first part of that - finding the containing
-object - is possible and practical on the PPC because of architectural
-artifcacts (fixed-width instructions and arcana of instruction encoding.)
-It's not possible on x86-64, but fortunately not necessary either (though
-the second part - adjusting the PC/RIP when the containing object moves)
-is both necessary and simple.</para>
+	<title>pc-locatives on the PPC</title>
+        <para>On the PPC, there's a third case (besides "node" and
+        "immediate" values).  As discussed below, a node that denotes
+        a memory-allocated lisp object is a biased (tagged) pointer
+        -to- that object; it's not generally possible to point -into-
+        some composite (multi-element) object (such a pointer would
+        not be a node, and the GC would have no way to update the
+        pointer if it were to move the underlying object.)</para>
+        <para>Such a pointer ("into" the interior of a heap-allocated
+        object) is often called a <emphasis>locative</emphasis>; the
+        cases where locatives are allowed in OpenMCL mostly involve
+        the behavior of function call and return instructions.  (To be
+        technicaly accurate, the other case also arises on x86-64, but
+        that case isn't as user-visible.)</para>
+        <para>On the PowerPC (both PPC32 and PPC64), all machine
+        instructions are 32 bits wide and all in1struction words are
+        allocated on 32-bit boundaries.  In PPC OpenMCL, a CODE-VECTOR
+        is a specialized type of vector-like object; its elements are
+        32-bit PPC machine instructions.  A CODE-VECTOR is an
+        attribute of FUNCTION object; a function call involves
+        accessing the function's code-vector and jumping to the
+        address of its first instruction.</para>
+        <para>As each instruction in the code vector sequentially
+        executes, the hardware program counter (PC) register advances
+        to the address of the next instruction (a locative into the
+        code vector); since PPC instructions are always 32 bits wide
+        and aligned on 32-bit boundaries, the low two bits of the PC
+        are always 0.  If the function executes a call (simple call
+        instrucions have the mnemonic "bl" on the PPC, which stands
+        for "branch and link"), the address of the next instruction
+        (also a word-aligned locative into a code-vector) is copied
+        into the special- purpose PPC "link register" (lr); a function
+        returns to its caller via a "branch to link register" (blr)
+        instruction.  Some cases of function call and return might
+        also use the PPC's "count register" (ctr), and if either the
+        lr or ctr needs to be stored in memory it needs to first be
+        copied to a general-purpose registers.</para>
+        <para>OpenMCL's GC understands that certain registers contain
+        these special "pc-locatives" (locatives that point into
+        CODE-VECTOR objects); it contains specal support for finding
+        the containing CODE-VECTOR object and for adjusting all of
+        these "pc-locatives" if the containing object is moved in
+        memory.  The first part of that - finding the containing
+        object - is possible and practical on the PPC because of
+        architectural artifcacts (fixed-width instructions and arcana
+        of instruction encoding.)  It's not possible on x86-64, but
+        fortunately not necessary either (though the second part -
+        adjusting the PC/RIP when the containing object moves) is both
+        necessary and simple.</para>
       </sect2>
 =

       <sect2 id=3D"Register-and-stack-usage-conventions">
-        <para>Register and stack usage conventions</para>
+        <title>Register and stack usage conventions</title>
 =

         <sect3 id=3D"Stack-conventions">
-          <para>Stack conventions
-On both PPC and X86 platforms, each lisp thread uses 3 stacks; the ways
-in which these stacks are used differs between the PPC and X86.</para>
+	  <title>Stack conventions</title>
+          <para>On both PPC and X86 platforms, each lisp thread uses 3
+          stacks; the ways in which these stacks are used differs
+          between the PPC and X86.</para>
           <para>Each thread has:</para>
-          <listitem mark=3D"bullet">
-            <variablelist>A "control stack".On both platforms, this is "th=
e stack" used by foreign code.On the PPC, it consists of a linked list of f=
rameswhere the first word in each frame points to the first word in theprev=
ious frame (and the outermost frame points to 0.)  Some frameson a PPC cont=
rol stack are lisp frames; lisp frames are always 4 wordsin size and contai=
n (in addition to the back pointer to the previousframe) the calling functi=
on (a node), the return address (a "locative"into the calling function's co=
de-vector), and the value to which thevalue-stack pointer (see below) shoul=
d be restored on function exit.On the PPC, the GC has to look at control-st=
ack frames, identifywhich of those frames are lisp frames, and treat the co=
ntents ofthe saved function slot as a node (and handle the return addresslo=
cative specially.)On x86-64, the control stack is used for dynamic-extent a=
llocationof immediate objects.  Since the control stack never contains node=
son x86-64, the GC ignores it on that platform.Alignment of the control sta=
ck follows the ABI conventions of theplatform (at least at any point in tim=
e where foreign code could run.)On PPC, the r1 register always points to th=
e top of the current thread'scontrol stack; on x86-64, the RSP register poi=
nts to the top of thecurrent thread's control stack when the thread is runn=
ing foreigncode and the address of the top of the control stack is kept in =
thethread's TCR see  when not running foreigncode.The control stack "grows =
down."</variablelist>
-            <variablelist>A "value stack".On both platforms, all values on=
 the value stack are nodes (including"tagged return addresses" on x86-64.) =
 The value stack is always alignedto the native word size; objects are alwa=
ys pushed on the value stackusing atomic instructions ("stwu"/"stdu" on PPC=
, "push" on x86-64), sothe contents of the value stack between its bottom a=
nd top are alwaysunambiguously nodes; the compiler usually tries to pop or =
discardnodes from the value stack as soon as possible after their last use(=
as soon as they may have become garbage.)On x86-64, the RSP register addres=
ses the top of the value stackwhen running lisp code; that address is saved=
 in the TCR whenrunning foreign code.On the PPC, a dedicated regiter (VSP, =
currently r15) is used toaddress the top of the value stack when running li=
sp code, and theVSP value is saved in the TCR when running foreign code.The=
 value stack grows down.</variablelist>
-            <variablelist>A "temp stack".The temp stack consists of a link=
ed list of frames, each of which pointsto the previous temp stack frame.  T=
he number of native machine wordsin each temp stack frame is always even, s=
o the temp stack is alignedon a two-word (64- or 128-bit) boundary.The temp=
 stack is used for dynamic-extent objects on both platforms;on the PPC, it'=
s used for essentially all such objects (regardlessof whether or not the ob=
jects contain nodes); on the x86-64, immediatedynamic-extent objects (strin=
gs, foreign pointers, etc.) are allocatedon the control stack and only node=
-containing dynamic-extent objectsare allocated on the temp stack.Data stru=
ctures used to implement CATCH and UNWIND-PROTECT are stored onthe temp sta=
ck on both ppc and x86-64.Temp stack frames are always doublenode aligned a=
nd objects withina temp stack frame are aligned on doublenode boundaries.  =
The firstword in each frame contains a back pointer to the previous frame; =
onthe PPC, the second word is used to indicate to the GC whethe theremainin=
g objects are nodes (if the second word is 0) or immediate(otherwise.)  On =
x86-64, where temp stack frames always contain nodes,the second word is alw=
ays 0.The temp stack grows down.  It usually takes several instuctions toal=
locate and safely initialize a temp stack frame that's intended tocontain n=
odes, and the GC has to recognize the case where a threadis in the process =
of allocating and initializing a temp stack frameand take care not to inter=
pret any uninitialized words in the frameas nodes.  See .The PPC keeps the =
current top of the temp stack in a dedicated register(TSP, currently r12) w=
hen running lisp code and saves this register'svalue in the TCR when runnin=
g foreign code.  The x86-64 keeps theaddress of the top of each thread's te=
mp stack in the thread's TCR.</variablelist>
-          =

-          </listitem>
+	  <itemizedlist>
+            <listitem>
+	      <para>A "control stack".On both platforms, this is "the
+	      stack" used by foreign code.On the PPC, it consists of a
+	      linked list of frameswhere the first word in each frame
+	      points to the first word in theprevious frame (and the
+	      outermost frame points to 0.)  Some frameson a PPC
+	      control stack are lisp frames; lisp frames are always 4
+	      wordsin size and contain (in addition to the back
+	      pointer to the previousframe) the calling function (a
+	      node), the return address (a "locative"into the calling
+	      function's code-vector), and the value to which
+	      thevalue-stack pointer (see below) should be restored on
+	      function exit.On the PPC, the GC has to look at
+	      control-stack frames, identifywhich of those frames are
+	      lisp frames, and treat the contents ofthe saved function
+	      slot as a node (and handle the return addresslocative
+	      specially.)On x86-64, the control stack is used for
+	      dynamic-extent allocationof immediate objects.  Since
+	      the control stack never contains nodeson x86-64, the GC
+	      ignores it on that platform.Alignment of the control
+	      stack follows the ABI conventions of theplatform (at
+	      least at any point in time where foreign code could
+	      run.)On PPC, the r1 register always points to the top of
+	      the current thread'scontrol stack; on x86-64, the RSP
+	      register points to the top of thecurrent thread's
+	      control stack when the thread is running foreigncode and
+	      the address of the top of the control stack is kept in
+	      thethread's TCR see when not running foreigncode.The
+	      control stack "grows down."</para>
+	    </listitem>
+            <listitem>
+	      <para>A "value stack".On both platforms, all values on
+	      the value stack are nodes (including"tagged return
+	      addresses" on x86-64.)  The value stack is always
+	      alignedto the native word size; objects are always
+	      pushed on the value stackusing atomic instructions
+	      ("stwu"/"stdu" on PPC, "push" on x86-64), sothe contents
+	      of the value stack between its bottom and top are
+	      alwaysunambiguously nodes; the compiler usually tries to
+	      pop or discardnodes from the value stack as soon as
+	      possible after their last use(as soon as they may have
+	      become garbage.)On x86-64, the RSP register addresses
+	      the top of the value stackwhen running lisp code; that
+	      address is saved in the TCR whenrunning foreign code.On
+	      the PPC, a dedicated regiter (VSP, currently r15) is
+	      used toaddress the top of the value stack when running
+	      lisp code, and theVSP value is saved in the TCR when
+	      running foreign code.The value stack grows down.</para>
+	    </listitem>
+	    <listitem>
+	      <para>A "temp stack".The temp stack consists of a linked
+	      list of frames, each of which pointsto the previous temp
+	      stack frame.  The number of native machine wordsin each
+	      temp stack frame is always even, so the temp stack is
+	      alignedon a two-word (64- or 128-bit) boundary.The temp
+	      stack is used for dynamic-extent objects on both
+	      platforms;on the PPC, it's used for essentially all such
+	      objects (regardlessof whether or not the objects contain
+	      nodes); on the x86-64, immediatedynamic-extent objects
+	      (strings, foreign pointers, etc.) are allocatedon the
+	      control stack and only node-containing dynamic-extent
+	      objectsare allocated on the temp stack.Data structures
+	      used to implement CATCH and UNWIND-PROTECT are stored
+	      onthe temp stack on both ppc and x86-64.Temp stack
+	      frames are always doublenode aligned and objects withina
+	      temp stack frame are aligned on doublenode boundaries.
+	      The firstword in each frame contains a back pointer to
+	      the previous frame; onthe PPC, the second word is used
+	      to indicate to the GC whethe theremaining objects are
+	      nodes (if the second word is 0) or immediate(otherwise.)
+	      On x86-64, where temp stack frames always contain
+	      nodes,the second word is always 0.The temp stack grows
+	      down.  It usually takes several instuctions toallocate
+	      and safely initialize a temp stack frame that's intended
+	      tocontain nodes, and the GC has to recognize the case
+	      where a threadis in the process of allocating and
+	      initializing a temp stack frameand take care not to
+	      interpret any uninitialized words in the frameas nodes.
+	      See .The PPC keeps the current top of the temp stack in
+	      a dedicated register(TSP, currently r12) when running
+	      lisp code and saves this register'svalue in the TCR when
+	      running foreign code.  The x86-64 keeps theaddress of
+	      the top of each thread's temp stack in the thread's
+	      TCR.</para>
+	    </listitem>
+          </itemizedlist>
         </sect3>
 =

         <sect3 id=3D"Register-conventions">
-          <para>Register conventions
-If there are a "reasonable" (for some value of "reasonable") number or
-general-purpose registers and the instruction set is "reasonably"
-orthogonal (most instructions that operate on GPRs can operate on any
-GPR), then it's possible to statically partition the GPRs into at least
-two sets: "immediate registers" never contain nodes, and "node registers"
-always contain nodes.  (On the PPC, a few registers are members of a
-third set of "PC locatives", and on both platforms some registers may
-have dedicated roles as stack or heap pointers; the latter class is
-treated as immediates by the GC proper but may be used to help determine
-the bounds of stack and heap memory areas.)</para>
-          <para>The ultimate definition of register partitioning is hardwi=
red
-into the GC in functions like "mark_xp()" and "forward_xp()", which
-process the values of some of the registers in an exception frame
-as nodes and may give some sort of special treatment to other register
-values they encounter there.)</para>
+	  <title>Register conventions</title>
+          <para>If there are a "reasonable" (for some value of
+          "reasonable") number or general-purpose registers and the
+          instruction set is "reasonably" orthogonal (most
+          instructions that operate on GPRs can operate on any GPR),
+          then it's possible to statically partition the GPRs into at
+          least two sets: "immediate registers" never contain nodes,
+          and "node registers" always contain nodes.  (On the PPC, a
+          few registers are members of a third set of "PC locatives",
+          and on both platforms some registers may have dedicated
+          roles as stack or heap pointers; the latter class is treated
+          as immediates by the GC proper but may be used to help
+          determine the bounds of stack and heap memory areas.)</para>
+	  <para>The ultimate definition of register partitioning is
+          hardwired into the GC in functions like "mark_xp()" and
+          "forward_xp()", which process the values of some of the
+          registers in an exception frame as nodes and may give some
+          sort of special treatment to other register values they
+          encounter there.)</para>
           <para>On x86-64, the static register partitioning scheme involve=
s:</para>
-          <listitem mark=3D"bullet">
-            <variablelist>(only) two "immediate" registers.The RAX and RDX=
 registers are used as the implicit operands andresults of some extended-pr=
ecision multiply and divide instructionswhich generally involve non-node va=
lues; since their use in theseinstructions means that they can't be guarant=
eed to contain nodevalues at all times, it's natural to put these registers=
 in the"immediate" set.  RAX is generally given the symbolic name "imm0",an=
d RDX is given the symbolic name "imm1"; you may see these namesin disassem=
bled code, usually in operations involving type checking,array indexing, an=
d foreign memory and function access.</variablelist>
-            <variablelist>(only) two "dedicated" registers.RSP and RBP hav=
e dedicated functionality dictated by the hardwareand calling conventions. =
 (There are a few places where RBP istemporarily used as an extra immediate=
 register.)</variablelist>
-            <variablelist>12 "node" registers.All other registers (RBX, RC=
X, RSI, RDI, and R8-R15) are asserted tocontain node values at (almost) all=
 times; legacy "string" operationsthat implicitly use RSI and/or RDI are no=
t used.  Shift and rotateintructions which shift/rotate by a variable numbe=
r of bits arerequired by the architecture to use the low byte of RCX (the t=
raditionalCL register) as the implicit shift count; when it's necessary to =
keepa non-node shift count in the low byte of RCX, the upper 7 bytes ofthe =
register are zeroed (so that misinterpetation of the immediatevalue in RCX =
as a node will not have negative GC affects.  (The GCmight briefly treate i=
t as a node, but since it's not pointing anywherenear the lisp heap it'll s=
oon lose interest in it.)Legacy instructions that use RCX (or some portions=
 of it) as a loopcounter can not be used (since such instructions might int=
roducenon-node values into RCX.)</variablelist>
-          =

-          </listitem>
+	  <itemizedlist>
+            <listitem>
+	      <para>(only) two "immediate" registers.The RAX and RDX
+	      registers are used as the implicit operands andresults
+	      of some extended-precision multiply and divide
+	      instructionswhich generally involve non-node values;
+	      since their use in theseinstructions means that they
+	      can't be guaranteed to contain nodevalues at all times,
+	      it's natural to put these registers in the"immediate"
+	      set.  RAX is generally given the symbolic name
+	      "imm0",and RDX is given the symbolic name "imm1"; you
+	      may see these namesin disassembled code, usually in
+	      operations involving type checking,array indexing, and
+	      foreign memory and function access.</para>
+	    </listitem>
+            <listitem>
+	      <para>(only) two "dedicated" registers.RSP and RBP have
+	      dedicated functionality dictated by the hardwareand
+	      calling conventions.  (There are a few places where RBP
+	      istemporarily used as an extra immediate
+	      register.)</para>
+	    </listitem>
+            <listitem>
+	      <para>12 "node" registers.All other registers (RBX, RCX,
+	      RSI, RDI, and R8-R15) are asserted tocontain node values
+	      at (almost) all times; legacy "string" operationsthat
+	      implicitly use RSI and/or RDI are not used.  Shift and
+	      rotateintructions which shift/rotate by a variable
+	      number of bits arerequired by the architecture to use
+	      the low byte of RCX (the traditionalCL register) as the
+	      implicit shift count; when it's necessary to keepa
+	      non-node shift count in the low byte of RCX, the upper 7
+	      bytes ofthe register are zeroed (so that
+	      misinterpetation of the immediatevalue in RCX as a node
+	      will not have negative GC affects.  (The GCmight briefly
+	      treate it as a node, but since it's not pointing
+	      anywherenear the lisp heap it'll soon lose interest in
+	      it.)Legacy instructions that use RCX (or some portions
+	      of it) as a loopcounter can not be used (since such
+	      instructions might introducenon-node values into
+	      RCX.)</para>
+</listitem>
+	  </itemizedlist>
           <para>On the PPC, the static register partitioning scheme involv=
es:</para>
-          <listitem mark=3D"bullet">
-            <variablelist>6 "immediate" registersRegisters r3-r8 are given=
 the symbolic names imm0-imm5.  As a RISCarchitecture with simpler addressi=
ng modes, the PPC probably usesimmediate registers a bit more often than th=
e CISC x86-64 does, butthey're generally used for the same sort of things (=
type checking,array indexing, FFI, etc.)</variablelist>
-            <variablelist>9 dedicated registers
-              <listitem mark=3D"bullet">
-                <variablelist>r0 (symbolic name rzero) always contains the=
 value 0 when runninglisp code.  Its value is sometimes read as 0 when it's=
 used as thebase register in a memory address; keeping the value 0 there is=
sometimes convenient and avoids asymmetry.</variablelist>
-                <variablelist>r1 (symbolic name sp) is the control stack p=
ointer, by PPC convention.</variablelist>
-                <variablelist>r2 is used to hold the current thread's TCR =
on ppc64 systems; it'snot used on ppc32.</variablelist>
-                <variablelist>r9 and r10 (symbolic names allocptr and allo=
cbase) are used to do per-thread memory allocation</variablelist>
-                <variablelist>r11 (symbolic name nargs) contains the numbe=
r of function arguments on entry and the number of return values in multipl=
e-value returning constructs.  It's not used more generally as either a nod=
e or immediate register because of the way that certain trap instruction en=
codings are interpreted.</variablelist>
-                <variablelist>r12 (symbolic name tsp) holds the top of the=
 current thread's temp stack.</variablelist>
-                <variablelist>r13 is used to hold the TCR on PPC32 sytems;=
 it's not used on PPC64.</variablelist>
-                <variablelist>r14 (symbolic name loc-pc) is used to copy "=
pc-locative" values between main memory and special-purpose PPC registers (=
LR and CTR) used in function-call and return instructions.</variablelist>
-                <variablelist>r15 (symbolic name vsp) addresses the top of=
 the current thread's value stack.</variablelist>
-                <variablelist>lr and ctr are PPC branch-unit registers use=
d in function call and return instructions; they're always treated as "pc-l=
ocatives", which precludes the use of the ctr in some PPC looping construct=
s.</variablelist>
+
+	  <itemizedlist>
+            <listitem>
+	      <para>6 "immediate" registersRegisters r3-r8 are given
+	      the symbolic names imm0-imm5.  As a RISCarchitecture
+	      with simpler addressing modes, the PPC probably
+	      usesimmediate registers a bit more often than the CISC
+	      x86-64 does, butthey're generally used for the same sort
+	      of things (type checking,array indexing, FFI,
+	      etc.)</para>
+	    </listitem>
+	    <listitem>
+	      <para>9 dedicated registers
+	      <itemizedlist>
+		<listitem>
+		  <para>r0 (symbolic name rzero) always contains the
+		  value 0 when runninglisp code.  Its value is
+		  sometimes read as 0 when it's used as thebase
+		  register in a memory address; keeping the value 0
+		  there issometimes convenient and avoids
+		  asymmetry.</para>
+		</listitem>
+		<listitem>
+		  <para>r1 (symbolic name sp) is the control stack
+		  pointer, by PPC convention.</para>
+		</listitem>
+                <listitem>
+		  <para>r2 is used to hold the current thread's TCR on
+		  ppc64 systems; it'snot used on ppc32.</para>
+		</listitem>
+                <listitem>
+		  <para>r9 and r10 (symbolic names allocptr and
+		  allocbase) are used to do per-thread memory
+		  allocation</para>
+		</listitem>
+                <listitem>
+		  <para>r11 (symbolic name nargs) contains the number
+		  of function arguments on entry and the number of
+		  return values in multiple-value returning
+		  constructs.  It's not used more generally as either
+		  a node or immediate register because of the way that
+		  certain trap instruction encodings are
+		  interpreted.</para>
+		</listitem>
+                <listitem>
+		  <para>r12 (symbolic name tsp) holds the top of the current thread's te=
mp stack.</para>
+		</listitem>
+		<listitem>
+		  <para>r13 is used to hold the TCR on PPC32 sytems; it's not used on PP=
C64.</para>
+		</listitem>
+		<listitem>
+		  <para>r14 (symbolic name loc-pc) is used to copy
+		  "pc-locative" values between main memory and
+		  special-purpose PPC registers (LR and CTR) used in
+		  function-call and return instructions.</para>
+		</listitem>
+                <listitem>
+		  <para>r15 (symbolic name vsp) addresses the top of
+		  the current thread's value stack.</para>
+		</listitem>
+		<listitem>
+		  <para>lr and ctr are PPC branch-unit registers used
+		  in function call and return instructions; they're
+		  always treated as "pc-locatives", which precludes
+		  the use of the ctr in some PPC looping
+		  constructs.</para>
+		</listitem>
               =

-              </listitem>
-</variablelist>
-            <variablelist>17 "node" registersr15-r31 are always treated as=
 node registers</variablelist>
-          =

-          </listitem>
+	      </itemizedlist>
+	      </para>
+	    </listitem>
+            <listitem>
+	      <para>17 "node" registersr15-r31 are always treated as
+	      node registers</para>
+	    </listitem>
+	    =

+          </itemizedlist>
         </sect3>
       </sect2>
 =

       <sect2 id=3D"Tagging-scheme">
-        <para>Tagging schemeOpenMCL always allocates lisp objects on doubl=
e-node (64-bit for 32-bit
-platforms, 128-bit for 64-bit platforms) boundaries; this mean that the
-low 3 bits (32-bit lisp) or 4 bits (64-bit lisp) are always 0 and are
-therefore redundant (we only really need to know the upper 29 or 60 bits
-in order to identify the aligned object address.)  The extra bits in a
-lisp node can be used to encode at least some information about the
-node's type, and the other 29/60 bits represent either an immediate
-value or a doublenode-aligned memory address.  The low 3 or 4 bits of a
-node are called the node's "tag bits", and the conventions used to
-encode type information in those tag bits are called a "tagging scheme."</=
para>
-        <para>It might be possible to use the same tagging scheme on all p=
latforms (at
-least on all platforms with the same word size and/or the same number of
-available tag bits), but there are often some strong reasons for not
-doing so.  These arguments tend to be very machine-specific: sometimes,
-there are fairly obvious machine-dependent tricks that can be exploited
-to make common operations on some types of tagged objects faster; other
-times, there are architectural restrictions that make it impractical to
-use certain tags for certain types.  (On PPC64, the "ld" (load
-doubleword) and "std" (store doubleword) instructions - which load and
-store a GPR operand at the effective address formed by adding the value
-of another GPR operand and a 16-bit constant operand - require that the
-low two bits of that constant operand be 0.  Since such instructions
-would typically be used to access the fields of things like CONS cells
-and structures, it's desirable that that the tags chosen for CONS cells
-and structures allow the use of these intructions as opposed to more
-expensive alternatives.)</para>
-        <para>One architecture-dependent tagging trick that works well on =
all
-architectures is to use a tag of 0 for FIXNUMs: a fixnum basically
-encodes its value shifted left a few bits and keeps those low bits
-clear. FIXNUM addition, subtraction, and binary logical operations can
-operate directly on the node operands, addition and subtraction can
-exploit hardware-based overflow detection, and (in the absence of
-overflow) the hardware result of those operations is a node (fixnum).
-Some other slightly-less-common operations may require a few extra
-instructions, but arithmetic operations on FIXNUMs should be as
-cheap as possible and using a tag of zero for FIXNUMs helps to
-ensure that it will be.</para>
-        <para>If we have N available tag bits (N =3D 3 for 32-bit OpenMCL =
and N =3D 4
-for 64-bit OpenMCL), this way of representing fixnums with the low
-M bits forced to 0 works as long as M <=3D N.  The smaller we make
-M, the larger the values of MOST-POSITIVE-FIXNUM and MOST-NEGATIVE
-become; the larger we make N, the more distinct non-FIXNUM tags
-become available.  A reasonable compromise is to choose M =3D N-1;
-this basically yields two distinct FIXNUM tags (one for even
-fixnums, one for odd fixnums), gives 30-bit fixnums on 32-bit
-platforms and 61-bit fixnums on 64-bit platforms, and leaves us
-with 6 or 14 tags to encoded other types.</para>
-        <para>Once we get past the assignment of FIXNUM tags, things quick=
ly devolve
-into machine-dependencies.  We can fairly easily see that we can't
-directly all other primitive lisp object types with only 6 or 14
-available tag values; the details of how types are encoded vary between
-the ppc32, ppc64, and x86-64 implementations, but there are some general
-common principles:</para>
-        <listitem mark=3D"bullet">
-          <variablelist>CONS cells always contain exactly 2 elements and a=
re usually fairly common.It therefore makes sense to give CONS cells their =
own tag.  Unlike thefixnum case - where a tag value of 0 had positive impli=
cations - theredoesn't seem to be any advantage to using any particular val=
ue.  (A longtime ago - in the case of 68K MCL - the CONS tag and the order =
of CARand CDR in memory were chosen to allow smaller, cheaper addressing mo=
desto be used to "cdr down a list."  That's not a factor on ppc or x86-64,b=
ut all versions of OpenMCL still store the CDR of a CONS cell first inmemor=
y.  It doesn't matter, but doing it the way that the host systemdid made bo=
ostrapping to a new target system a little easier.)</variablelist>
-          <variablelist>Any way you look at it, NIL is a bit ... unusual.N=
IL is both a SYMBOL and a LIST (as well as being a canonical truthvalue and=
 probably a few other things.)  Its role as a LIST is probablymuch more imp=
ortant to most programs than its role as a SYMBOL is:LISTP has to be true o=
f NIL and primitives like CAR and CDR do LISTPimplicitly when safe and want=
 that operation to be fast.There are several possible approaches to this; O=
penMCL uses two of them.On PPC32 and X86-64, NIL is basically a weird CONS =
cell that straddlestwo doublenodes; the tag of NIL is unique and congruent =
modulo 4 (modulo8 on 64-bit) with the tag used for CONS cells.  LISTP is th=
ereforetrue of any node whose low 2 (or 3) bits contain the appropriate tag=
value (it's not otherwise necessary to special-case NIL.)  SYMBOLaccessors =
(SYMBOL-NAME, SYMBOL-VALUE, SYMBOL-PLIST ..) -do- haveto special-case NIL (=
and access the components of an internal proxysymbol.)On PPC64 (where archi=
tectural restrictions dictate the set of tagsthat can be used to access fix=
ed components of an object), thatapproach wasn't practical.  NIL is just a =
distinguished SYMBOL,and it just happens to be the case that its pname slot=
 and valueslots are at the same offsets from a tagged pointer as a CONS cel=
lsCDR and CAR would be.  NIL's pname is set to NIL (SYMBOL-NAMEchecks for t=
his and returns the string "NIL"), and LISTP (andtherefore safe CAR and CDR=
) have to check for (OR NULL CONSP).At least in the case of CAR and CDR, th=
e fact that the PPC hasmultiple condition-code fields keeps that extra test=
 from beingprohibitively expensive.</variablelist>
-          <variablelist>Some objects are immediate.(but not FIXNUMs).This =
is true of CHARACTERs and, on 64-bit platforms, SINGLE-FLOATs.It's also tru=
e of some nodes used in the runtime system (specialvalues used to indicate =
unbound variables and slots, for instance.)On 64-bit platforms, SINGLE-FLOA=
Ts have their own unique tag (makingthem a little easier to recognize; on a=
ll platforms, CHARACTERs sharea tag with other immediate objects (unbound m=
arkers) but are easyto recognize (by looking at several of their low bits.)=
  The GCtreats any node with an immediate tag (and any node with a fixnumta=
g) as a leaf.</variablelist>
-          <variablelist>There are some advantages to treating everything e=
lse - memory-allocated objects that aren't CONS cells - uniformly.There are=
 some disadvantages to that uniform treatment as well, and thetreatment of =
"memory-allocated non-CONS objects" isn't entirely uniformaccross all OpenM=
CL implementations.  Let's first pretend that thetreatment is uniform, then=
 discuss the ways in which it isn't.The "uniform approach" is to treat all =
memory-allocated non-CONS objectsas if they were vectors; this use of the t=
erm is a little looser thanwhat's implied by the CL VECTOR type.  OpenMCL a=
ctually uses the term"uvector" to mean "a memory-allocated lisp object othe=
r than a CONS cell,whose first word is a header which describes the object'=
s type andthe number of elements that it contains."  In this view, a SYMBOL=
 isa UVECTOR, as is a STRING, a STANDARD-INSTANCE, a CL array or vector,a F=
UNCTION, and even a DOUBLE-FLOAT.In the PPC implementations (where things a=
re a little more ... uniform),a single tag value is used to denote any uvec=
tor; in order to determinesomething more specific about the type of the obj=
ect in question, it'snecessary to fetch the low byte of the header word fro=
m memory.  On thex86-64 platform, certain types of uvectors - SYMBOLs and F=
UNCTIONs -are given their own unique tags.  The good news about the x86-64 =
approachis that SYMBOLs and FUNCTIONs can be recognized without referencing=
memory; the slightly bad news is that primitive operations that workon UVEC=
TOR-tagged objects - like the function CCL:UVREF - don't workon SYMBOLs or =
FUNCTIONs on x86-64 (but -do- work on those types of objectsin the PPC port=
s.)The header word which precedes a UVECTOR's data in memory contains 8bits=
 of type information in the low byte and either 24 or 56 bits of"element-co=
unt" information in the rest of the word.  (This is wherethe sometimes-limi=
ting value of 2^24 for ARRAY-TOTAL-SIZE-LIMIT onPPC32 platforms comes from.=
)  The low byte of the header - sometimescalled the uvector's subtag - is i=
tself tagged (which means thatthe header is tagged.)  The (3 or 4) tag bits=
 in the subtag are usedto determine whether the uvector's elements are node=
s or immediates.(A UVECTOR whose elements are nodes is called a GVECTOR; a =
UVECTORwhose elements are immediates is called an IVECTOR.  This terminolog=
ycame from Spice Lisp, which was a predecessor of CMUCL.)Even though a uvec=
tor header is tagged, a header is not a node.  There'sno (supported) way to=
 get your hands on one in lisp and doing so couldbe dangerous.  (If the val=
ue of a header wound up in a lisp noderegister and that register wound up g=
etting pushed on a thread's valuestack, the GC might misinterpret that situ=
ation to mean that therewas a stack-allocated UVECTOR on the value stack.)<=
/variablelist>
+	<title>Tagging scheme</title>
+        <para>OpenMCL always allocates lisp objects on double-node
+        (64-bit for 32-bit platforms, 128-bit for 64-bit platforms)
+        boundaries; this mean that the low 3 bits (32-bit lisp) or 4
+        bits (64-bit lisp) are always 0 and are therefore redundant
+        (we only really need to know the upper 29 or 60 bits in order
+        to identify the aligned object address.)  The extra bits in a
+        lisp node can be used to encode at least some information
+        about the node's type, and the other 29/60 bits represent
+        either an immediate value or a doublenode-aligned memory
+        address.  The low 3 or 4 bits of a node are called the node's
+        "tag bits", and the conventions used to encode type
+        information in those tag bits are called a "tagging
+        scheme."</para>
+        <para>It might be possible to use the same tagging scheme on
+        all platforms (at least on all platforms with the same word
+        size and/or the same number of available tag bits), but there
+        are often some strong reasons for not doing so.  These
+        arguments tend to be very machine-specific: sometimes, there
+        are fairly obvious machine-dependent tricks that can be
+        exploited to make common operations on some types of tagged
+        objects faster; other times, there are architectural
+        restrictions that make it impractical to use certain tags for
+        certain types.  (On PPC64, the "ld" (load doubleword) and
+        "std" (store doubleword) instructions - which load and store a
+        GPR operand at the effective address formed by adding the
+        value of another GPR operand and a 16-bit constant operand -
+        require that the low two bits of that constant operand be 0.
+        Since such instructions would typically be used to access the
+        fields of things like CONS cells and structures, it's
+        desirable that that the tags chosen for CONS cells and
+        structures allow the use of these intructions as opposed to
+        more expensive alternatives.)</para>
+        <para>One architecture-dependent tagging trick that works well
+        on all architectures is to use a tag of 0 for FIXNUMs: a
+        fixnum basically encodes its value shifted left a few bits and
+        keeps those low bits clear. FIXNUM addition, subtraction, and
+        binary logical operations can operate directly on the node
+        operands, addition and subtraction can exploit hardware-based
+        overflow detection, and (in the absence of overflow) the
+        hardware result of those operations is a node (fixnum).  Some
+        other slightly-less-common operations may require a few extra
+        instructions, but arithmetic operations on FIXNUMs should be
+        as cheap as possible and using a tag of zero for FIXNUMs helps
+        to ensure that it will be.</para> =

+	<para>If we have N available tag bits (N =3D 3 for 32-bit
+	OpenMCL and N =3D 4 for 64-bit OpenMCL), this way of
+	representing fixnums with the low M bits forced to 0 works as
+	long as M &lt;=3D N.  The smaller we make M, the larger the
+	values of MOST-POSITIVE-FIXNUM and MOST-NEGATIVE become; the
+	larger we make N, the more distinct non-FIXNUM tags become
+	available.  A reasonable compromise is to choose M =3D N-1; this
+	basically yields two distinct FIXNUM tags (one for even
+	fixnums, one for odd fixnums), gives 30-bit fixnums on 32-bit
+	platforms and 61-bit fixnums on 64-bit platforms, and leaves
+	us with 6 or 14 tags to encoded other types.</para>
+        <para>Once we get past the assignment of FIXNUM tags, things
+        quickly devolve into machine-dependencies.  We can fairly
+        easily see that we can't directly all other primitive lisp
+        object types with only 6 or 14 available tag values; the
+        details of how types are encoded vary between the ppc32,
+        ppc64, and x86-64 implementations, but there are some general
+        common principles:</para>
+
+	<itemizedlist>
+	  <listitem>
+	    <para>CONS cells always contain exactly 2 elements and are
+	    usually fairly common.It therefore makes sense to give
+	    CONS cells their own tag.  Unlike thefixnum case - where a
+	    tag value of 0 had positive implications - theredoesn't
+	    seem to be any advantage to using any particular value.
+	    (A longtime ago - in the case of 68K MCL - the CONS tag
+	    and the order of CAR and CDR in memory were chosen to allow
+	    smaller, cheaper addressing modes to be used to "cdr down a
+	    list."  That's not a factor on ppc or x86-64,but all
+	    versions of OpenMCL still store the CDR of a CONS cell
+	    first in memory.  It doesn't matter, but doing it the way
+	    that the host system did made boostrapping to a new target
+	    system a little easier.)
+	    </para>
+	  </listitem>
+	  <listitem>
+	    <para>Any way you look at it, NIL is a bit ... unusual.NIL
+	    is both a SYMBOL and a LIST (as well as being a canonical
+	    truth value and probably a few other things.)  Its role as
+	    a LIST is probably much more important to most programs
+	    than its role as a SYMBOL is:LISTP has to be true of NIL
+	    and primitives like CAR and CDR do LISTP implicitly when
+	    safe and want that operation to be fast.There are several
+	    possible approaches to this; OpenMCL uses two of them. On
+	    PPC32 and X86-64, NIL is basically a weird CONS cell that
+	    straddles two doublenodes; the tag of NIL is unique and
+	    congruent modulo 4 (modulo 8 on 64-bit) with the tag used
+	    for CONS cells.  LISTP is therefore true of any node whose
+	    low 2 (or 3) bits contain the appropriate tag value (it's
+	    not otherwise necessary to special-case NIL.)
+	    SYMBOL accessors (SYMBOL-NAME, SYMBOL-VALUE, SYMBOL-PLIST
+	    ..) -do- have to special-case NIL (and access the
+	    components of an internal proxy symbol.) On PPC64 (where
+	    architectural restrictions dictate the set of tags that can
+	    be used to access fixed components of an object),
+	    that approach wasn't practical.  NIL is just a
+	    distinguished SYMBOL,and it just happens to be the case
+	    that its pname slot and values lots are at the same offsets
+	    from a tagged pointer as a CONS cell's CDR and CAR would be.
+	    NIL's pname is set to NIL (SYMBOL-NAME checks for this and
+	    returns the string "NIL"), and LISTP (and therefore safe
+	    CAR and CDR) have to check for (OR NULL CONSP).At least in
+	    the case of CAR and CDR, the fact that the PPC has multiple
+	    condition-code fields keeps that extra test from
+	    being prohibitively expensive.</para>
+	  </listitem>
+	  <listitem>
+	    <para>Some objects are immediate.(but not FIXNUMs).This is
+	    true of CHARACTERs and, on 64-bit platforms,
+	    SINGLE-FLOATs.It's also true of some nodes used in the
+	    runtime system (specialvalues used to indicate unbound
+	    variables and slots, for instance.)On 64-bit platforms,
+	    SINGLE-FLOATs have their own unique tag (makingthem a
+	    little easier to recognize; on all platforms, CHARACTERs
+	    sharea tag with other immediate objects (unbound markers)
+	    but are easyto recognize (by looking at several of their
+	    low bits.)  The GCtreats any node with an immediate tag
+	    (and any node with a fixnumtag) as a leaf.</para>
+	  </listitem>
+          <listitem>
+	    <para>There are some advantages to treating everything
+	    else - memory-allocated objects that aren't CONS cells -
+	    uniformly.There are some disadvantages to that uniform
+	    treatment as well, and the treatment of "memory-allocated
+	    non-CONS objects" isn't entirely uniformaccross all
+	    OpenMCL implementations.  Let's first pretend that
+	    the treatment is uniform, then discuss the ways in which it
+	    isn't.The "uniform approach" is to treat all
+	    memory-allocated non-CONS objectsas if they were vectors;
+	    this use of the term is a little looser thanwhat's implied
+	    by the CL VECTOR type.  OpenMCL actually uses the
+	    term"uvector" to mean "a memory-allocated lisp object
+	    other than a CONS cell,whose first word is a header which
+	    describes the object's type andthe number of elements that
+	    it contains."  In this view, a SYMBOL isa UVECTOR, as is a
+	    STRING, a STANDARD-INSTANCE, a CL array or vector,a
+	    FUNCTION, and even a DOUBLE-FLOAT.In the PPC
+	    implementations (where things are a little more
+	    ... uniform),a single tag value is used to denote any
+	    uvector; in order to determinesomething more specific
+	    about the type of the object in question, it'snecessary to
+	    fetch the low byte of the header word from memory.  On
+	    thex86-64 platform, certain types of uvectors - SYMBOLs
+	    and FUNCTIONs -are given their own unique tags.  The good
+	    news about the x86-64 approachis that SYMBOLs and
+	    FUNCTIONs can be recognized without referencingmemory; the
+	    slightly bad news is that primitive operations that workon
+	    UVECTOR-tagged objects - like the function CCL:UVREF -
+	    don't workon SYMBOLs or FUNCTIONs on x86-64 (but -do- work
+	    on those types of objectsin the PPC ports.)The header word
+	    which precedes a UVECTOR's data in memory contains 8bits
+	    of type information in the low byte and either 24 or 56
+	    bits of"element-count" information in the rest of the
+	    word.  (This is wherethe sometimes-limiting value of 2^24
+	    for ARRAY-TOTAL-SIZE-LIMIT onPPC32 platforms comes from.)
+	    The low byte of the header - sometimescalled the uvector's
+	    subtag - is itself tagged (which means thatthe header is
+	    tagged.)  The (3 or 4) tag bits in the subtag are usedto
+	    determine whether the uvector's elements are nodes or
+	    immediates.(A UVECTOR whose elements are nodes is called a
+	    GVECTOR; a UVECTORwhose elements are immediates is called
+	    an IVECTOR.  This terminologycame from Spice Lisp, which
+	    was a predecessor of CMUCL.)Even though a uvector header
+	    is tagged, a header is not a node.  There'sno (supported)
+	    way to get your hands on one in lisp and doing so couldbe
+	    dangerous.  (If the value of a header wound up in a lisp
+	    noderegister and that register wound up getting pushed on
+	    a thread's valuestack, the GC might misinterpret that
+	    situation to mean that therewas a stack-allocated UVECTOR
+	    on the value stack.)</para>
+	  </listitem>
         =

-        </listitem>
+	</itemizedlist>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"Heap-Allocation">
-      <para>Heap Allocation
-When the OpenMCL kernel first starts up, a large contiguous chunk of the
-process's address space is mapped as "anonymous, no access" memory. ("Larg=
e"
-means different things in different contexts; on LinuxPPC32, it means "abo=
ut
-1 gigabyte", on DarwinPPC32, it means "about 2 gigabytes", and on current
-64-bit platforms it ranges from 128 to 512 gigabytes, depending on OS. The=
se
-values are both defaults and upper limits; the &ndash;heap-reserve argumen=
t can
-be used to try to reserve less than the default.)</para>
-      <para>Reserving address space that can't (yet) be read or written to=
 doesn't
-cost much; in particular, it doesn't require that correspinding swap
-space or physical memory be available.  Marking the address range as being
-"mapped" helps to ensure that other things (random calls to malloc(),
-dynamically loaded shared libraries) won't be allocated in this region
-that lisp has reserved for its own heap growth.</para>
-      <para>A small portion (around 1/32 on 32-bit platforms and 1/64 on 6=
4-bit
-platforms) of that large chunk of address space is reserved for GC
-data structures.  Memory pages reserved for these data structures are
-mapped read-write as pages made writable in the main portion of the
-heap.</para>
-      <para>The initial heap image is mapped into this reserved address sp=
ace and
-an additional (LISP-HEAP-GC-THRESHOLD) bytes are mapped read-write.
-GC data structures grow to match the amount of GC-able memory in the
-initial image + the gc threshold, and control is transferred to lisp
-code.  Inevitably, that code spoils everything and starts consing;
-there are basically three layers of memory allocation that can go on.</par=
a>
+      <title>Heap Allocation</title> <para>When the OpenMCL kernel
+      first starts up, a large contiguous chunk of the process's
+      address space is mapped as "anonymous, no access"
+      memory. ("Large" means different things in different contexts;
+      on LinuxPPC32, it means "about 1 gigabyte", on DarwinPPC32, it
+      means "about 2 gigabytes", and on current 64-bit platforms it
+      ranges from 128 to 512 gigabytes, depending on OS. These values
+      are both defaults and upper limits; the --heap-reserve
+      argument can be used to try to reserve less than the
+      default.)</para>
+      <para>Reserving address space that can't (yet) be read or
+      written to doesn't cost much; in particular, it doesn't require
+      that correspinding swap space or physical memory be available.
+      Marking the address range as being "mapped" helps to ensure that
+      other things (result from random calls to malloc(), dynamically
+      loaded shared libraries) won't be allocated in this region that
+      lisp has reserved for its own heap growth.</para>
+      <para>A small portion (around 1/32 on 32-bit platforms and 1/64
+      on 64-bit platforms) of that large chunk of address space is
+      reserved for GC data structures.  Memory pages reserved for
+      these data structures are mapped read-write as pages made
+      writable in the main portion of the heap.</para>
+      <para>The initial heap image is mapped into this reserved
+      address space and an additional (LISP-HEAP-GC-THRESHOLD) bytes
+      are mapped read-write.  GC data structures grow to match the
+      amount of GC-able memory in the initial image + the gc
+      threshold, and control is transferred to lisp code.  Inevitably,
+      that code spoils everything and starts consing; there are
+      basically three layers of memory allocation that can go
+      on.</para>
 =

       <sect2 id=3D"Per-thread-object-allocation">
-        <para>Per-thread object allocationEach lisp thread has a private "=
reserved memory segment"; when a thread
-starts up, its reserved memory segment is empty.  PPC ports maintain the
-highest unallocated addres and he lowest allocated address in the
-current segment in registers when running lisp code; on x86-664, these
-values are maintained in the current threads's TCR.  (An "empty" heap
-segment is one whose high pointer and low pointer are equal.)  When
-a thread is not in the midde of allocating something, the low 3 or
-4 bits of the high and low pointers are clear (the pointers are
-doublenode-aligned.)</para>
-        <para>A thread tries to allocate an object whose physical size in =
bytes is X
-and whose tag is Y by:</para>
-        <varlistentry numeration=3D"arabic">
-          <variablelist>decrementing the "high" pointer by (- X Y)</variab=
lelist>
-          <variablelist>trapping if the high pointer is less than the low =
pointer</variablelist>
-          <variablelist>using the (tagged) high pointer to initialize the =
object, if necessary</variablelist>
-          <variablelist>clearing the low bits of the high pointer</variabl=
elist>
-        </varlistentry>
-        <para>On PPC32, where the size of a CONS cell is 8 bytes and the t=
ag of a CONS
-cell is 1, machine code which sets the arg_z register to the result of
-doing (CONS arg_y arg_z) looks like:</para>
+	<title>Per-thread object allocation</title>
+        <para>Each lisp thread has a private "reserved memory
+        segment"; when a thread starts up, its reserved memory segment
+        is empty.  PPC ports maintain the highest unallocated addres
+        and he lowest allocated address in the current segment in
+        registers when running lisp code; on x86-664, these values are
+        maintained in the current threads's TCR.  (An "empty" heap
+        segment is one whose high pointer and low pointer are equal.)
+        When a thread is not in the midde of allocating something, the
+        low 3 or 4 bits of the high and low pointers are clear (the
+        pointers are doublenode-aligned.)</para>
+        <para>A thread tries to allocate an object whose physical size
+        in bytes is X and whose tag is Y by:</para>
+	<orderedlist>
+	  <listitem>
+	    <para>decrementing the "high" pointer by (- X Y)</para>
+	  </listitem>
+	  <listitem>
+	    <para>trapping if the high pointer is less than the low
+	    pointer</para>
+	  </listitem>
+	  <listitem>
+	    <para>using the (tagged) high pointer to initialize the
+	    object, if necessary</para>
+	  </listitem>
+	  <listitem>
+	    <para>clearing the low bits of the high pointer</para>
+	  </listitem>
+	</orderedlist>
+        <para>On PPC32, where the size of a CONS cell is 8 bytes and
+        the tag of a CONS cell is 1, machine code which sets the arg_z
+        register to the result of doing (CONS arg_y arg_z) looks
+        like:</para>
         <programlisting>
   (SUBI ALLOCPTR ALLOCPTR 7)    ; decrement the high pointer by (- 8 1)
   (TWLLT ALLOCPTR ALLOCBASE)    ; trap if the high pointer is below the ba=
se
@@ -10250,11 +14593,12 @@
   (MR ARG_Z ALLOCPTR)           ; arg_z is the new CONS cell
   (RLWINM ALLOCPTR ALLOCPTR 0 0 28)     ; clear tag bits
 </programlisting>
-        <para>On x86-64, the idea's similar but the implementation is diff=
erent.  The
-high and low pointers to the current thread's reserved segment are kept
-in the TCR, which is addressed by the gs segment register. An x86-64
-CONS cell is 16 bytes wide and has a tag of 3; we canonically use the
-temp0 register to initialize the object</para>
+        <para>On x86-64, the idea's similar but the implementation is
+        different.  The high and low pointers to the current thread's
+        reserved segment are kept in the TCR, which is addressed by
+        the gs segment register. An x86-64 CONS cell is 16 bytes wide
+        and has a tag of 3; we canonically use the temp0 register to
+        initialize the object</para>
         <programlisting>
   (subq ($ 13) ( (% gs) 216))  ; decrement allocptr
   (movq ( (% gs) 216) (% temp0)); load allocptr into temp0
@@ -10266,53 +14610,63 @@
   (movq (% arg_y) ( 5 (% temp0))) ; set the car
   (movq (% arg_z) ( -3 (% temp0))); set the cdr
   (movq (% temp0) (% arg_z))    ; return the cons
-</programlisting>
-        <para>If we don't take the trap (if allocating 8-16 bytes doesn't =
exhaust
-the thread's reserved memory segment), that's a fairly short and
-simple instruction sequence.  If we do take the trap, we'll have to
-do some additional work in order to get a new segment for the current
-thread.</para>
+	</programlisting>
+        <para>If we don't take the trap (if allocating 8-16 bytes
+        doesn't exhaust the thread's reserved memory segment), that's
+        a fairly short and simple instruction sequence.  If we do take
+        the trap, we'll have to do some additional work in order to
+        get a new segment for the current thread.</para>
       </sect2>
 =

       <sect2 id=3D"Allocation-of-reserved-heap-segments">
-        <para>Allocation of reserved heap segmentsAfter lisp image is firs=
t mapped into memory - and after each full GC - the
-lisp kernel ensures that (LISP-HEAP-GC-TRESHOLD) additional bytes beyond
-the current end of the heap are mapped read-write.</para>
-        <para>If a thread traps while trying to allocate memory, the threa=
d goes
-through the usual exception-handling protocol (to ensure that any oher
-thread that GCs "sees" the state of the trapping thread and to serialize
-exception handling.)  When the exception handler runs, it determines
-the nature and size of the failed allocation and tries to complete the
-allocation on the thread's behalf (and leave it with a reasonably large
-thread-specific memory segment so that the next small allocation is
-unlikely to trap.</para>
-        <para>Depending on the size of the requested segment allocation, t=
he number of
-segment allocations that have occurred since the last GC, and the EGC
-and GC thresholds, the segment allocation trap handler may invoke a full
-or ephemeral GC before returning a new segment.  It's worth noting that
-the [E]GC is triggered based on the number of and size of these segments
-that've been allocated since the last GC; it doesn't have much to do
-with how "full" each of those per-thread segments are.  It's possible
-for a large number of threads to do fairly incidental memory allocation
-and trigger the GC as a result; avoiding this involves tuning the
-per-thread allocation quantum and the GC/EGC thresholds appropriately.</pa=
ra>
+	<title>Allocation of reserved heap segments</title>
+        <para>After lisp image is first mapped into memory - and after
+        each full GC - the lisp kernel ensures that
+        (LISP-HEAP-GC-TRESHOLD) additional bytes beyond the current
+        end of the heap are mapped read-write.</para>
+        <para>If a thread traps while trying to allocate memory, the
+        thread goes through the usual exception-handling protocol (to
+        ensure that any oher thread that GCs "sees" the state of the
+        trapping thread and to serialize exception handling.)  When
+        the exception handler runs, it determines the nature and size
+        of the failed allocation and tries to complete the allocation
+        on the thread's behalf (and leave it with a reasonably large
+        thread-specific memory segment so that the next small
+        allocation is unlikely to trap.</para>
+        <para>Depending on the size of the requested segment
+        allocation, the number of segment allocations that have
+        occurred since the last GC, and the EGC and GC thresholds, the
+        segment allocation trap handler may invoke a full or ephemeral
+        GC before returning a new segment.  It's worth noting that the
+        [E]GC is triggered based on the number of and size of these
+        segments that've been allocated since the last GC; it doesn't
+        have much to do with how "full" each of those per-thread
+        segments are.  It's possible for a large number of threads to
+        do fairly incidental memory allocation and trigger the GC as a
+        result; avoiding this involves tuning the per-thread
+        allocation quantum and the GC/EGC thresholds
+        appropriately.</para>
       </sect2>
 =

       <sect2 id=3D"Heap-growth">
-        <para>Heap growthAll OSes on which OpenMCL currently runs use an "=
overcommit" memory
-allocation strategy by default (though some of them provide ways of
-overriding that default.)  What this means in general is that the OS
-doesn't necessarily ensure that backing store is available when asked
-to map pages as read-write; it'll often return a success indicator from
-the mapping attempt (mapping the pages as "zero-fill, copy-on-write"),
-and only try to allocate the backing store (swap space and/or physical
-memory) when non-zero contents are written to the pages.</para>
-        <para>It -sounds- like it'd be better to have the mmap() call fail
-immediately, but it's actually a complicated issue.  (It's possible that
-other applications will stop using some backing store before lisp code
-actually touches the pages that need it, for instance.)  It's also
-not guaranteed that lisp code would be able to "cleanly" signal an
-out-of-memory condition if lisp is ... out of memory</para>
+	<title>Heap growth</title>
+        <para>All OSes on which OpenMCL currently runs use an
+        "overcommit" memory allocation strategy by default (though
+        some of them provide ways of overriding that default.)  What
+        this means in general is that the OS doesn't necessarily
+        ensure that backing store is available when asked to map pages
+        as read-write; it'll often return a success indicator from the
+        mapping attempt (mapping the pages as "zero-fill,
+        copy-on-write"), and only try to allocate the backing store
+        (swap space and/or physical memory) when non-zero contents are
+        written to the pages.</para>
+        <para>It -sounds- like it'd be better to have the mmap() call
+        fail immediately, but it's actually a complicated issue.
+        (It's possible that other applications will stop using some
+        backing store before lisp code actually touches the pages that
+        need it, for instance.)  It's also not guaranteed that lisp
+        code would be able to "cleanly" signal an out-of-memory
+        condition if lisp is ... out of memory</para>
         <para>I don't know that I've ever seen an abrupt out-of-memory fai=
lure that
 wasn't preceeded by several minutes of excessive paging activity.  The
 most expedient course in cases like this is to either (a) use less memory
@@ -10322,410 +14676,539 @@
     </sect1>
 =

     <sect1 id=3D"GC-details">
-      <para>GC details
-The GC uses a Mark/Compact algorithm; its execution time is
-essentially a factor of the amount of live data in the heap. (The somewhat
-better-known Mark/Sweep algorithms don't compact the live data but instead
-traverse the garbage to rebuild free-lists; their execution time is
-therefore a factor of the total heap size.)</para>
+      <title>GC details</title>
+      <para>The GC uses a Mark/Compact algorithm; its
+      execution time is essentially a factor of the amount of live
+      data in the heap. (The somewhat better-known Mark/Sweep
+      algorithms don't compact the live data but instead traverse the
+      garbage to rebuild free-lists; their execution time is therefore
+      a factor of the total heap size.)</para>
       <para>As mentioned in , two auxiliary data structures
-(proportional to the size of the lisp heap) are maintained. These are</par=
a>
-      <varlistentry numeration=3D"arabic">
-        <variablelist>the markbits bitvector, which contains a bit for eve=
rydoublenode in the dynamic heap (plus a few extra words for alignmentand s=
o that sub-bitvectors can start on word boundaries.)</variablelist>
-        <variablelist>the relocation table, which contains a native word f=
or every 32 or 64doublenodes in the dynamic heap, plus an extra word used t=
o keep trackof the end of the heap.</variablelist>
-      </varlistentry>
-      <para>The total GC space overhead is therefore on the order of 3% (2=
/64 or
-1/32).</para>
+      (proportional to the size of the lisp heap) are maintained. These ar=
e</para>
+      <orderedlist>
+	<listitem>
+	  <para>the markbits bitvector, which contains a bit for
+	  everydoublenode in the dynamic heap (plus a few extra words
+	  for alignmentand so that sub-bitvectors can start on word
+	  boundaries.)</para>
+	</listitem>
+	<listitem>
+	  <para>the relocation table, which contains a native word for
+	  every 32 or 64 doublenodes in the dynamic heap, plus an
+	  extra word used to keep trackof the end of the heap.</para>
+	</listitem>
+      </orderedlist>
+      <para>The total GC space overhead is therefore on the order of
+      3% (2/64 or 1/32).</para>
       <para>The general algorithm proceeds as follows:</para>
 =

       <sect2 id=3D"Mark-phase">
-        <para>Mark phase
-Each doublenode in the dynamic heap has a corresponding bit in the
-markbits vector. (For any doublenode in the heap, the index of its mark
-bit is determined by subtracing the address of the start of the heap
-from the address of the object and dividing the result by 8 or 16.) The GC
-knows the markbit index of the free pointer, so determining that the
-markbit index of a doubleword address is between the start of the heap
-and the free pointer can be done with a single unsigned
-comparison.</para>
-        <para>The markbits of all doublenodes in the dynamic heap are zero=
ed
-before the mark phase begins. An object is <emphasis>marked</emphasis>
-if the markbits of all of its constituent doublewords are set and
-unmarked otherwise; setting an object's markbits involves setting the
-corrsponding markbits of all constituent doublenodes in the
-object.</para>
-        <para>The mark phase traverses each root. If the tag of the value =
of
-the root indicates that it's a non-immediate node whose address lies
-in the lisp heap, then:</para>
-        <varlistentry numeration=3D"arabic">
-          <variablelist>If the object is already marked, do nothing.</vari=
ablelist>
-          <variablelist>Set the object's markbit(s).</variablelist>
-          <variablelist>If the object is an ivector, do nothing further.</=
variablelist>
-          <variablelist>If the object is a cons cell, recursively mark its=
 car andcdr.</variablelist>
-          <variablelist>Otherwise, the object is a gvector. Recursively ma=
rk itselements.</variablelist>
-        </varlistentry>
-        <para>Marking an object thus involves ensuring that its mark bits =
are set and
-then recursively marking any pointers contained within the object if the
-object was originally unmarked. If this recursive step was implemented
-in the obvious manner, marking an object would take stack space
-proportional to the length of the pointer chain from some root to that
-object. Rather than storing that pointer chain implicitly on the stack
-(in a series of recursive calls to the mark subroutine), the OpenMCL
-marker uses mixture of recursion and a technique called <emphasis>link
-inversion</emphasis> to store the pointer chain in the objects themselves.
-(Recursion tends to be simpler and faster; if a recursive step notes
-that stack space is becoming limited, the link-inversion technique is
-used.)</para>
+	<title>Mark phase</title>
+        <para>Each doublenode in the dynamic heap has a corresponding
+        bit in the markbits vector. (For any doublenode in the heap,
+        the index of its mark bit is determined by subtracing the
+        address of the start of the heap from the address of the
+        object and dividing the result by 8 or 16.) The GC knows the
+        markbit index of the free pointer, so determining that the
+        markbit index of a doubleword address is between the start of
+        the heap and the free pointer can be done with a single
+        unsigned comparison.</para>
+        <para>The markbits of all doublenodes in the dynamic heap are
+        zeroed before the mark phase begins. An object is
+        <emphasis>marked</emphasis> if the markbits of all of its
+        constituent doublewords are set and unmarked otherwise;
+        setting an object's markbits involves setting the corrsponding
+        markbits of all constituent doublenodes in the object.</para>
+        <para>The mark phase traverses each root. If the tag of the
+        value of the root indicates that it's a non-immediate node
+        whose address lies in the lisp heap, then:</para>
+	<orderedlist>
+	  <listitem>
+	    <para>If the object is already marked, do nothing.</para>
+	  </listitem>
+	  <listitem>
+	    <para>Set the object's markbit(s).</para>
+	  </listitem>
+	  <listitem>
+	    <para>If the object is an ivector, do nothing further.</para>
+	  </listitem>
+	  <listitem>
+	    <para>If the object is a cons cell, recursively mark its
+	    car and cdr.</para>
+	  </listitem>
+	  <listitem>
+	    <para>Otherwise, the object is a gvector. Recursively mark
+	    itselements.</para>
+	  </listitem>
+	</orderedlist>
+        <para>Marking an object thus involves ensuring that its mark
+        bits are set and then recursively marking any pointers
+        contained within the object if the object was originally
+        unmarked. If this recursive step was implemented in the
+        obvious manner, marking an object would take stack space
+        proportional to the length of the pointer chain from some root
+        to that object. Rather than storing that pointer chain
+        implicitly on the stack (in a series of recursive calls to the
+        mark subroutine), the OpenMCL marker uses mixture of recursion
+        and a technique called <emphasis>link inversion</emphasis> to
+        store the pointer chain in the objects themselves.  (Recursion
+        tends to be simpler and faster; if a recursive step notes that
+        stack space is becoming limited, the link-inversion technique
+        is used.)</para>
         <para>Certain types of objects are treated a little specially:</pa=
ra>
-        <varlistentry numeration=3D"arabic">
-          <variablelist>To support a feature called <emphasis>GCTWA
-              <tip>
-<para>I believe that theacronym comes from MACLISP, where it stood for "Ga=
rbage Collection ofTruly Worthless Atoms".</para>
-              </tip>
-, </emphasis>the vector which contains the internalsymbols of the current =
package is marked on entry to the mark phasebut the symbols themselves are =
not marked at this time. Near the endof the mark phase, symbols referenced =
from this vector which are nototherwise marked are marked if and only if th=
ey're somehowdistinguishable from newly created symbols (by virtue of their=
 havingfunction bindings, value bindings, plists, or other attributes.)</va=
riablelist>
-          <variablelist>Pools have their first element set to NIL before a=
ny otherelements are marked.</variablelist>
-          <variablelist>All hash tables have certain fields (used to cache=
 previousresults) invalidated.</variablelist>
-          <variablelist>Weak Hash Tables and other weak objects are put on=
 a linkedlist as they're encountered; their contents are only retained ifth=
ere are other (non-weak) references to them.</variablelist>
-        </varlistentry>
+	<orderedlist>
+	<listitem>
+	  <para>To support a feature called <emphasis>GCTWA
+              <footnote>
+		<para>I believe that theacronym comes from MACLISP,
+		where it stood for "Garbage Collection ofTruly
+		Worthless Atoms".</para>
+              </footnote>
+	      , </emphasis>the vector which contains the
+	      internalsymbols of the current package is marked on
+	      entry to the mark phasebut the symbols themselves are
+	      not marked at this time. Near the endof the mark phase,
+	      symbols referenced from this vector which are
+	      nototherwise marked are marked if and only if they're
+	      somehowdistinguishable from newly created symbols (by
+	      virtue of their havingfunction bindings, value bindings,
+	      plists, or other attributes.)</para>
+	</listitem>
+	<listitem>
+	  <para>Pools have their first element set to NIL before any
+	  otherelements are marked.</para>
+	</listitem>
+	<listitem>
+	  <para>All hash tables have certain fields (used to cache
+	  previous results) invalidated.</para>
+	</listitem>
+	<listitem>
+	  <para>Weak Hash Tables and other weak objects are put on a
+	  linkedlist as they're encountered; their contents are only
+	  retained if there are other (non-weak) references to
+	  them.</para>
+	</listitem>
+	</orderedlist>
         <para>At the end of the mark phase, the markbits of all objects wh=
ich
-are transitively reachable from the roots are set and all other markbits
-are clear.</para>
+	are transitively reachable from the roots are set and all other markbits
+	are clear.</para>
       </sect2>
 =

       <sect2 id=3D"Relocation-phase">
-        <para>Relocation phase
-The <emphasis>forwarding address</emphasis> of a doublenode in the
-dynamic heap is (<its current address> - (size_of_doublenode * <the number=
 of
-unmarked markbits that precede it>)) or alternately (<the base of
-the heap> + (size_of_doublenode * <the number of marked markbits that prec=
ed
-it>)). Rather than count the number of preceding markbits each time,
-the relocation table is used to precompute an approximation of the
-forwarding addresses for all doublewords. Given this approximate address
-and a pointer into the markbits vector, it's relatively easy to compute
-the exact forwarding address.</para>
-        <para>The relocation table contains the forwarding addresses of ea=
ch
-<emphasis>pagelet</emphasis>, where a pagelet is 256 bytes (or 32
-doublenodes). The forwarding address of the first pagelet is the base of
-the heap. The forwarding address of the second pagelet is the sum of the
-forwarding address of the first and 8 bytes for each mark bit set in the
-first 32-bit word in the markbits table. The last entry in the
-relocation table contains the forwarding address that the freepointer
-would have, e.g., the new value of the freepointer after
-compaction.</para>
-        <para>In many programs, old objects rarely become garbage and new
-objects often do. When building the relocation table, the relocation
-phase notes the address of the first unmarked object in the dynamic
-heap. Only the area of the heap between the first unmarked object and
-the freepointer needs to be compacted; only pointers to this area will
-need to be forwarded (the forwarding address of all other pointers to
-the dynamic heap is the address of that pointer.) Often, the first
-unmarked object is much nearer the free pointer than it is to the base
-of the heap.</para>
+	<title>Relocation phase</title>
+	<para>The <emphasis>forwarding address</emphasis> of a
+	doublenode in the dynamic heap is (&lt;its current address> -
+	(size_of_doublenode * &lt;the number of unmarked markbits that
+	precede it>)) or alternately (&lt;the base of the heap> +
+	(size_of_doublenode * &lt;the number of marked markbits that
+	preced it &gt;)). Rather than count the number of preceding
+	markbits each time, the relocation table is used to precompute
+	an approximation of the forwarding addresses for all
+	doublewords. Given this approximate address and a pointer into
+	the markbits vector, it's relatively easy to compute the exact
+	forwarding address.</para>
+	<para>The relocation table contains the forwarding addresses
+	of each <emphasis>pagelet</emphasis>, where a pagelet is 256
+	bytes (or 32 doublenodes). The forwarding address of the first
+	pagelet is the base of the heap. The forwarding address of the
+	second pagelet is the sum of the forwarding address of the
+	first and 8 bytes for each mark bit set in the first 32-bit
+	word in the markbits table. The last entry in the relocation
+	table contains the forwarding address that the freepointer
+	would have, e.g., the new value of the freepointer after
+	compaction.</para>
+	<para>In many programs, old objects rarely become garbage and
+	new objects often do. When building the relocation table, the
+	relocation phase notes the address of the first unmarked
+	object in the dynamic heap. Only the area of the heap between
+	the first unmarked object and the freepointer needs to be
+	compacted; only pointers to this area will need to be
+	forwarded (the forwarding address of all other pointers to the
+	dynamic heap is the address of that pointer.)  Often, the
+	first unmarked object is much nearer the free pointer than it
+	is to the base of the heap.</para>
       </sect2>
 =

       <sect2 id=3D"Forwarding-phase">
-        <para>Forwarding phase
-The forwarding phase traverses all roots and the
-"old" part of the dynamic heap (the part between the base
-of the heap and the first unmarked object.) All references to objects
-whose address is between the first unmarked object and the free pointer
-are updated to point to the address the object will have after
-compaction by using the relocation table and the markbits vector and
-interpolating.</para>
-        <para>The relocation table entry for the pagelet nearest the objec=
t is
-found. If the pagelet's address is less than the object's address, the
-number of set markbits that precede the object on the pagelet is used to
-determine the object's address; otherwise, the number of set markbits
-the follow the object on the pagelet is used.</para>
-        <para>Since forwarding views the heap as a set of doublewords, loc=
atives
-are (mostly) treated like any other pointers. (The basic difference is
-that locatives may appear to be tagged as fixnums, in which case they're
-treated as word-aligned pointers into the object.)</para>
-        <para>If the forward phase changes the address of any hash table k=
ey in
-a hash table that hashes by address (e.g., an EQ hash table), it sets a
-bit in the hash table's header. The hash table code will rehash the hash
-table's contents if it tries to do a lookup on a key in such a
-table.</para>
-        <para>Profiling reveals that about half of the total time spent in=
 the
-GC is spent in the subroutine which determines a pointer's forwarding
-address. Exploiting GCC-specific idioms, hand-coding the routine, and
-inlining calls to it could all be expected to improve GC
-performance.</para>
+	<title>Forwarding phase</title>
+        <para>The forwarding phase traverses all roots and the "old"
+        part of the dynamic heap (the part between the base of the
+        heap and the first unmarked object.) All references to objects
+        whose address is between the first unmarked object and the
+        free pointer are updated to point to the address the object
+        will have after compaction by using the relocation table and
+        the markbits vector and interpolating.</para>
+	<para>The relocation table entry for the pagelet nearest the
+	object is found. If the pagelet's address is less than the
+	object's address, the number of set markbits that precede the
+	object on the pagelet is used to determine the object's
+	address; otherwise, the number of set markbits the follow the
+	object on the pagelet is used.</para>
+        <para>Since forwarding views the heap as a set of doublewords,
+        locatives are (mostly) treated like any other pointers. (The
+        basic difference is that locatives may appear to be tagged as
+        fixnums, in which case they're treated as word-aligned
+        pointers into the object.)</para>
+        <para>If the forward phase changes the address of any hash
+        table key in a hash table that hashes by address (e.g., an EQ
+        hash table), it sets a bit in the hash table's header. The
+        hash table code will rehash the hash table's contents if it
+        tries to do a lookup on a key in such a table.</para>
+        <para>Profiling reveals that about half of the total time
+        spent in the GC is spent in the subroutine which determines a
+        pointer's forwarding address. Exploiting GCC-specific idioms,
+        hand-coding the routine, and inlining calls to it could all be
+        expected to improve GC performance.</para>
       </sect2>
 =

       <sect2 id=3D"Compact-phase">
-        <para>Compact phase
-The compact phase compacts the area between the first unmarked
-object and the freepointer so that it contains only marked objects.
-While doing so, it forwards any pointers it finds in the objects it
-copies.</para>
-        <para>When the compact phase is finished, so is the GC (more or le=
ss):
-the free pointer and some other data structures are updated and control
-returns to the exception handler that invoked the GC. If sufficient
-memory has been freed to satisfy any allocation request that may have
-triggered the GC, the exception handler returns; otherwise, a
-"seriously low on memory" condition is signalled, possibly
-after releasing a small emergency pool of memory.</para>
+	<title>Compact phase</title>
+        <para>The compact phase compacts the area between the first
+        unmarked object and the freepointer so that it contains only
+        marked objects.  While doing so, it forwards any pointers it
+        finds in the objects it copies.</para>
+        <para>When the compact phase is finished, so is the GC (more
+        or less): the free pointer and some other data structures are
+        updated and control returns to the exception handler that
+        invoked the GC. If sufficient memory has been freed to satisfy
+        any allocation request that may have triggered the GC, the
+        exception handler returns; otherwise, a "seriously low on
+        memory" condition is signalled, possibly after releasing a
+        small emergency pool of memory.</para>
       </sect2>
     </sect1>
 =

     <sect1 id=3D"The-ephemeral-GC">
-      <para>The ephemeral GC
-In the OpenMCL memory management scheme, the relative age of two
-objects in the dynamic heap can be determined by their addresses: if
-addresses X and Y are both addresses in the dynamic heap, X is younger
-than Y (X was created more recently than Y) if it is nearer to the free
-pointer (and farther from the base of the heap) than Y.</para>
-      <para>Ephemeral (or generational) garbage collectors attempt to expl=
oit
-the following assumptions:</para>
-      <listitem mark=3D"bullet">
-        <variablelist>most newly created objects become garbage soon after=
 they'recreated.</variablelist>
-        <variablelist>most objects that have already survived several GCs =
are unlikelyto ever become garbage.</variablelist>
-        <variablelist>old objects can only point to newer objects as the r=
esult of adestructive modification (e.g., via SETF.)</variablelist>
+      <title>The ephemeral GC</title>
+      <para>In the OpenMCL memory management scheme, the relative age
+      of two objects in the dynamic heap can be determined by their
+      addresses: if addresses X and Y are both addresses in the
+      dynamic heap, X is younger than Y (X was created more recently
+      than Y) if it is nearer to the free pointer (and farther from
+      the base of the heap) than Y.</para>
+      <para>Ephemeral (or generational) garbage collectors attempt to
+      exploit the following assumptions:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>most newly created objects become garbage soon after
+	  they'recreated.</para>
+	</listitem>
+	<listitem>
+	  <para>most objects that have already survived several GCs
+	  are unlikely to ever become garbage.</para>
+	</listitem>
+	<listitem>
+	  <para>old objects can only point to newer objects as the
+	  result of adestructive modification (e.g., via
+	  SETF.)</para>
+	</listitem>
+      </itemizedlist>
+
+      <para>By concentrating its efforts on (frequently and quickly)
+      reclaiming newly created garbage, an ephemeral collector hopes
+      to postpone the more costly full GC as long as possible. It's
+      important to note that most programs create some long-lived
+      garbage, so an EGC can't typically eliminate the need for full
+      GC.</para>
+      <para>An EGC views each object in the heap as belonging to
+      exactly one <emphasis>generation</emphasis>; generations are
+      sets of objects that are related to each other by age: some
+      generation is the youngest, some the oldest, and there's an age
+      relationship between any intervening generations. Objects are
+      typically assigned to the youngest generation when first
+      allocated; any object that has survived some number of GCs in
+      its current generation is promoted (or
+      <emphasis>tenured</emphasis>) into an older generation.</para>
+      <para>When a generation is GCed, the roots consist of the
+      stacks, registers, and global variables as always and also of
+      any pointers to objects in that generation from other
+      generations. To avoid the need to scan those (often large) other
+      generations looking for such intergenerational references, the
+      runtime system must note all such intergenerational references
+      at the point where they're created (via Setf).<footnote><para>This is
+      sometimes called "The Write Barrier": all assignments which
+      might result in intergenerational references must be noted, as
+      if the other generations were write-protected.</para></footnote> The
+      set of pointers that may contain intergenerational references is
+      sometimes called <emphasis>the remembered set</emphasis>.</para>
+      <para>In OpenMCL's EGC, the heap is organized exactly the same
+      as otherwise; "generations" are merely structures which contain
+      pointers to regions of the heap (which is already ordered by
+      age.) When a generation needs to be GCed, any younger generation
+      is incorporated into it; all objects which survive a GC of a
+      given generation are promoted into the next older
+      generation. The only intergenerational references that can exist
+      are therefore those where an old object is modified to contain a
+      pointer to a new object.</para>
+      <para>The EGC uses exactly the same code as the full GC. When a
+      given GC is "ephemeral",</para>
+      <itemizedlist>
+        <listitem>
+	  <para>the "base of the heap" used to determine anobject's
+	  markbit address is the base of the generation
+	  being collected;</para>
+	</listitem>
+        <listitem>
+	  <para>the markbits vector is actually a pointer into the
+	  middle of the global markbits table; preceding entries in
+	  this table are used to note doubleword addresses in older
+	  generations that (may) contain intergenerational
+	  references;</para>
+	</listitem>
+        <listitem>
+	  <para>some steps (notably GCTWA and the handling of weak
+	  objects) are not performed;</para>
+	</listitem>
+        <listitem>
+	  <para>the intergenerational references table is used to
+	  findadditional roots for the mark and forward phases. If a
+	  bit is set inthe intergenerational references table, that
+	  means that thecorresponding doubleword (in some "old"
+	  generation, insome "earlier" part of the heap) may have had
+	  a pointerto an object in a younger generation stored into
+	  it.</para>
+	</listitem>
       =

-      </listitem>
-      <para>By concentrating its efforts on (frequently and quickly) recla=
iming
-newly created garbage, an ephemeral collector hopes to postpone the more
-costly full GC as long as possible. It's important to note that most
-programs create some long-lived garbage, so an EGC can't typically
-eliminate the need for full GC.</para>
-      <para>An EGC views each object in the heap as belonging to exactly o=
ne
-<emphasis>generation</emphasis>; generations are sets of objects that are
-related to each other by age: some generation is the youngest, some the
-oldest, and there's an age relationship between any intervening
-generations. Objects are typically assigned to the youngest generation
-when first allocated; any object that has survived some number of GCs in
-its current generation is promoted (or <emphasis>tenured</emphasis>) into
-an older generation.</para>
-      <para>When a generation is GCed, the roots consist of the stacks,
-registers, and global variables as always and also of any pointers to
-objects in that generation from other generations. To avoid the need to
-scan those (often large) other generations looking for such
-intergenerational references, the runtime system must note all such
-intergenerational references at the point where they're created (via
-Setf).<tip><para>This is sometimes called "The Write Barrier": all
-assignments which might result in intergenerational references must be
-noted, as if the other generations were write-protected.</para></tip> The =
set of pointers that may contain intergenerational
-references is sometimes called <emphasis>the remembered
-set</emphasis>.</para>
-      <para>In OpenMCL's EGC, the heap is organized exactly the same as ot=
herwise;
-"generations" are merely structures which contain pointers to
-regions of the heap (which is already ordered by age.) When a generation
-needs to be GCed, any younger generation is incorporated into it; all
-objects which survive a GC of a given generation are promoted into the
-next older generation. The only intergenerational references that can
-exist are therefore those where an old object is modified to contain a
-pointer to a new object.</para>
-      <para>The EGC uses exactly the same code as the full GC. When a give=
n GC
-is "ephemeral",</para>
-      <listitem mark=3D"bullet">
-        <variablelist>the "base of the heap" used to determine anobject's =
markbit address is the base of the generation beingcollected;</variablelist>
-        <variablelist>the markbits vector is actually a pointer into the m=
iddle of theglobal markbits table; preceding entries in this table are used=
 tonote doubleword addresses in older generations that (may) containinterge=
nerational references;</variablelist>
-        <variablelist>some steps (notably GCTWA and the handling of weak o=
bjects) arenot performed;</variablelist>
-        <variablelist>the intergenerational references table is used to fi=
ndadditional roots for the mark and forward phases. If a bit is set inthe i=
ntergenerational references table, that means that thecorresponding doublew=
ord (in some "old" generation, insome "earlier" part of the heap) may have =
had a pointerto an object in a younger generation stored into it.</variable=
list>
-      =

-      </listitem>
-      <para>The intergenerational references table is maintained indirectl=
y:
-whenever a setf operation that may introduce an intergenerational
-reference occurs, a pointer to the doubleword being stored into is pushed
-onto the <emphasis>memo buffer</emphasis>, which is a stack whos top is
-addressed by the memo register. Whenever the memo buffer
-overflows<tip><para>A guard page at the end of the memo buffer simplifies =
overflow
-detection.</para></tip> when the EGC is active, the handler scans the buff=
er and
-sets bits in the intergenerational references table for each doubleword
-address it finds in the buffer that belongs to some generation other than
-the youngest; the same scan is performed on entry to any ephemeral GC.
-After (possibly) performing this scan, the handler resets the memo
-register to point to the bottom of the memo stack; this means that when
-the EGC is inactive, the memo buffer is constantly being filled and
-emptied for no apparent reason.</para>
-      <para>With one exception (the implicit setfs that occur on entry to =
and
-exit from the binding of a special variable), all setfs that might
-introduce an intergenerational reference must be memoized.<tip><para>Note =
that the implicit setfs that occur when initializing an
-object - as in the case of a call to cons or vector - can't introduce
-intergenerational references, since the newly created object is always
-younger than the objects used to initialize it.</para></tip> It's always s=
afe to push any cons cell or gvector locative
-onto the memo stack; it's never safe to push anything else.</para>
-      <para>Typically, the intergenerational references bitvector is spars=
e: a
-relatively small number of old locations are stored into, although some of
-them may have been stored into many times. The routine that scans the
-memoization buffer does a lot of work and usually does it fairly often; it
-uses a simple, brute-force method but might run faster if it was smarter
-about recognizing addresses that it'd already seen.</para>
-      <para>When the EGC mark and forward phases scan the intergenerational
-reference bits, they can clear any bits that denote doublewords that
-definitely do not contain intergenerational references.</para>
+      </itemizedlist>
+      <para>The intergenerational references table is maintained
+      indirectly: whenever a setf operation that may introduce an
+      intergenerational reference occurs, a pointer to the doubleword
+      being stored into is pushed onto the <emphasis>memo
+      buffer</emphasis>, which is a stack whos top is addressed by the
+      memo register. Whenever the memo buffer overflows<tip><para>A
+      guard page at the end of the memo buffer simplifies overflow
+      detection.</para></tip> when the EGC is active, the handler
+      scans the buffer and sets bits in the intergenerational
+      references table for each doubleword address it finds in the
+      buffer that belongs to some generation other than the youngest;
+      the same scan is performed on entry to any ephemeral GC.  After
+      (possibly) performing this scan, the handler resets the memo
+      register to point to the bottom of the memo stack; this means
+      that when the EGC is inactive, the memo buffer is constantly
+      being filled and emptied for no apparent reason.</para>
+      <para>With one exception (the implicit setfs that occur on entry
+      to and exit from the binding of a special variable), all setfs
+      that might introduce an intergenerational reference must be
+      memoized.<tip><para>Note that the implicit setfs that occur when
+      initializing an object - as in the case of a call to cons or
+      vector - can't introduce intergenerational references, since the
+      newly created object is always younger than the objects used to
+      initialize it.</para></tip> It's always safe to push any cons
+      cell or gvector locative onto the memo stack; it's never safe to
+      push anything else.</para>
+      <para>Typically, the intergenerational references bitvector is
+      sparse: a relatively small number of old locations are stored
+      into, although some of them may have been stored into many
+      times. The routine that scans the memoization buffer does a lot
+      of work and usually does it fairly often; it uses a simple,
+      brute-force method but might run faster if it was smarter about
+      recognizing addresses that it'd already seen.</para>
+      <para>When the EGC mark and forward phases scan the
+      intergenerational reference bits, they can clear any bits that
+      denote doublewords that definitely do not contain
+      intergenerational references.</para>
     </sect1>
 =

     <sect1 id=3D"Fasl-files">
-      <para>Fasl files
-The information in this section was current in November 2004.
-Saving and loading of Fasl files is implemented in
-xdump/faslenv.lisp, level-0/nfasload.lisp, and lib/nfcomp.lisp.
-The information here is only an overview, which might help when
-reading the source.</para>
-      <para>The OpenMCL Fasl format is forked from the old MCL Fasl format=
; there
-are a few differences, but they are minor.  The name "nfasload"
-comes from the fact that this is the so-called "new" Fasl system,
-which was true in 1986 or so.  The format has held up well, although
-it would certainly need extensions to deal with 64-bit data, and
-some other modernization might be possible.</para>
-      <para>A Fasl file begins with a "file header", which contains version
-information and a count of the following "blocks".  There's typically
-only one "block" per Fasl file.  The blocks are part of a mechanism
-for
-combining multiple logical files into a single physical file, in order
-to simplify the distribution of precompiled programs.  (Nobody seems
-to be doing anything interesting with this feature, at the moment,
-probably because it isn't documented.)</para>
-      <para>Each block begins with a header for itself, which just describ=
es the
-size of the data that follows.</para>
-      <para>The data in each block is treated as a simple stream of bytes,=
 which
-define a bytecode program.  The actual bytecodes, "fasl operators",
-are defined in xdump/faslenv.lisp.  The descriptions in the source
-file are terse, but, according to Gary, "probably accurate".</para>
-      <para>Some of the operators are used to create a per-block "object t=
able",
-which
-is a vector used to keep track of previously-loaded objects and
-simplify references to them.  When the table is created, an index
-associated with it is set to zero; this is analogous to an array
-fill-pointer, and allows the table to be treated like a stack.</para>
-      <para>The low seven bits of each bytecode are used to specify the
-fasl operator;
-currently, about fifty operators are defined.  The high byte, when
-set, indicates that the result of the operation should be pushed
-onto the object table.</para>
-      <para>Most bytecodes are followed by operands; the operand data is
-byte-aligned.
-How many operands there are, and their type, depend on the bytecode.
-Operands can be indices into the object table, immediate values, or
-some combination of these.</para>
-      <para>An exception is the bytecode #xFF, which has the symbolic name
-ccl::$faslend; it is used to mark the end of the block.</para>
+      <title>Fasl files</title>
+      <para>The information in this section was current in November
+      2004.  Saving and loading of Fasl files is implemented in
+      xdump/faslenv.lisp, level-0/nfasload.lisp, and lib/nfcomp.lisp.
+      The information here is only an overview, which might help when
+      reading the source.</para>
+      <para>The OpenMCL Fasl format is forked from the old MCL Fasl
+      format; there are a few differences, but they are minor.  The
+      name "nfasload" comes from the fact that this is the so-called
+      "new" Fasl system, which was true in 1986 or so.  The format has
+      held up well, although it would certainly need extensions to
+      deal with 64-bit data, and some other modernization might be
+      possible.</para>
+      <para>A Fasl file begins with a "file header", which contains
+      version information and a count of the following "blocks".
+      There's typically only one "block" per Fasl file.  The blocks
+      are part of a mechanism for combining multiple logical files
+      into a single physical file, in order to simplify the
+      distribution of precompiled programs.  (Nobody seems to be doing
+      anything interesting with this feature, at the moment, probably
+      because it isn't documented.)</para>
+      <para>Each block begins with a header for itself, which just
+      describes the size of the data that follows.</para>
+      <para>The data in each block is treated as a simple stream of
+      bytes, which define a bytecode program.  The actual bytecodes,
+      "fasl operators", are defined in xdump/faslenv.lisp.  The
+      descriptions in the source file are terse, but, according to
+      Gary, "probably accurate".</para>
+      <para>Some of the operators are used to create a per-block
+      "object table", which is a vector used to keep track of
+      previously-loaded objects and simplify references to them.  When
+      the table is created, an index associated with it is set to
+      zero; this is analogous to an array fill-pointer, and allows the
+      table to be treated like a stack.</para>
+      <para>The low seven bits of each bytecode are used to specify
+      the fasl operator; currently, about fifty operators are defined.
+      The high byte, when set, indicates that the result of the
+      operation should be pushed onto the object table.</para>
+      <para>Most bytecodes are followed by operands; the operand data
+      is byte-aligned.  How many operands there are, and their type,
+      depend on the bytecode.  Operands can be indices into the object
+      table, immediate values, or some combination of these.</para>
+      <para>An exception is the bytecode #xFF, which has the symbolic
+      name ccl::$faslend; it is used to mark the end of the
+      block.</para>
     </sect1>
 =

-    <sect1 id=3D"Heap-images">
-      <para>Heap images
-Needs complete rewrite.</para>
-    </sect1>
-
-    <sect1 id=3D"Operating-system-dependencies">
-      <para>Operating system dependencies</para>
-    </sect1>
+
 =

     <sect1 id=3D"The-Objective-C-Bridge--1-">
-      <para>The Objective-C Bridge
-Unlike the rest of this chapter, this section was written in late
-2004.</para>
+      <title>The Objective-C Bridge</title>
 =

       <sect2 id=3D"How-OpenMCL-Recognizes-Objective-C-Objects">
-        <para>How OpenMCL Recognizes Objective-C Objects
-In most cases, pointers to instances of Objective-C classes are
-recognized as such; the recognition is (and probably always will be)
-slightly heuristic. Basically, any pointer that passes basic sanity
-checks and whose first word is a pointer to a known ObjC class is
-considered to be an instance of that class; the Objective-C runtime
-system would reach the same conclusion.</para>
-        <para>It's certainly possible that a random pointer to an arbitrary
-memory address could look enough like an ObjC instance to fool the lisp
-runtime system, and it's possible that pointers could have their
-contents change so that something that had either been a true ObjC
-instance (or had looked a lot like one) is changed (possibly by virtue
-of having been deallocated.)</para>
-        <para>In the first case, we can improve the heuristics substantial=
ly: we
-can make stronger assertions that a particular pointer is really "of
-type :ID" when it's a parameter to a function declared to take
-such a pointer as an argument or a similarly declared function result; we
-can be more confident of something we obtained via SLOT-VALUE of a slot
-defined to be of type :ID than if we just dug a pointer out of memory
-somewhere.</para>
-        <para>The second case is a little more subtle: ObjC memory managem=
ent is
-based on a reference-counting scheme, and it's possible for an
-object to ... cease to be an object while lisp is still referencing it.
-If we don't want to deal with this possibility (and we don't),
-we'll basically have to ensure that the object is not deallocated
-while lisp is still thinking of it as a first-class object. There's
-some support for this in the case of objects created with MAKE-INSTANCE,
-but we may need to give similar treatment to foreign objects that are
-introduced to the lisp runtime in other ways (as function arguments,
-return values, SLOT-VALUE results, etc. as well as those instances
-that're created under lisp control.)</para>
-        <para>This doesn't all work yet (in fact, not much of it works yet=
);
-in practice, this has not yet been as much of a problem as anticipated,
-but that may be because existing Cocoa code deals primarily with
-relatively long-lived objects such as windows, views, menus, etc.</para>
+	<title>How OpenMCL Recognizes Objective-C Objects</title>
+        <para>In most cases, pointers to instances of Objective-C
+        classes are recognized as such; the recognition is (and
+        probably always will be) slightly heuristic. Basically, any
+        pointer that passes basic sanity checks and whose first word
+        is a pointer to a known ObjC class is considered to be an
+        instance of that class; the Objective-C runtime system would
+        reach the same conclusion.</para>
+        <para>It's certainly possible that a random pointer to an
+        arbitrary memory address could look enough like an ObjC
+        instance to fool the lisp runtime system, and it's possible
+        that pointers could have their contents change so that
+        something that had either been a true ObjC instance (or had
+        looked a lot like one) is changed (possibly by virtue of
+        having been deallocated.)</para>
+        <para>In the first case, we can improve the heuristics
+        substantially: we can make stronger assertions that a
+        particular pointer is really "of type :ID" when it's a
+        parameter to a function declared to take such a pointer as an
+        argument or a similarly declared function result; we can be
+        more confident of something we obtained via SLOT-VALUE of a
+        slot defined to be of type :ID than if we just dug a pointer
+        out of memory somewhere.</para>
+        <para>The second case is a little more subtle: ObjC memory
+        management is based on a reference-counting scheme, and it's
+        possible for an object to ... cease to be an object while lisp
+        is still referencing it.  If we don't want to deal with this
+        possibility (and we don't), we'll basically have to ensure
+        that the object is not deallocated while lisp is still
+        thinking of it as a first-class object. There's some support
+        for this in the case of objects created with MAKE-INSTANCE,
+        but we may need to give similar treatment to foreign objects
+        that are introduced to the lisp runtime in other ways (as
+        function arguments, return values, SLOT-VALUE results, etc. as
+        well as those instances that're created under lisp
+        control.)</para>
+        <para>This doesn't all work yet (in fact, not much of it works
+        yet); in practice, this has not yet been as much of a problem
+        as anticipated, but that may be because existing Cocoa code
+        deals primarily with relatively long-lived objects such as
+        windows, views, menus, etc.</para>
       </sect2>
 =

-      <sect2 id=3D"Recommended-Reading--1-">
-        <para>Recommended Reading</para>
-        <term><indexterm>The Apple Objective-C Runtime Reference
-            <variablelist>This describes the internal data structures and =
programminginterface of Objective C as it is implemented on OS X.</variable=
list>
-          </indexterm>
-        </term>
+      <sect2>
+	<title>Recommended Reading</title>
+
+	<variablelist>
+	  <varlistentry>
+	    <term>
+	      <ulink url=3D"http://developer.apple.com/documentation/Cocoa/">Coco=
a Documentation</ulink>
+	    </term>
+	    =

+	   <listitem>
+	     <para>
+	       This is the top page for all of Apple's documentation on
+	       Cocoa.  If you are unfamiliar with Cocoa, it is a good
+	       place to start.
+	     </para>
+	   </listitem>
+	</varlistentry>
+	<varlistentry>
+	  <term>
+	    <ulink url=3D"http://developer.apple.com/documentation/Cocoa/Referenc=
e/Foundation/ObjC_classic/index.html">Foundation Reference for Objective-C<=
/ulink>
+	  </term>
+
+	  <listitem>
+	    <para>
+	      This is one of the two most important Cocoa references; it
+	      covers all of the basics, except for GUI programming.  This is
+	      a reference, not a tutorial.
+	    </para>
+	  </listitem>
+	</varlistentry>
+      </variablelist>
       </sect2>
     </sect1>
   </chapter>
 =

+
   <chapter id=3D"Modifying-OpenMCL">
-    <para>Modifying OpenMCL</para>
+    <title>Modifying OpenMCL</title>
 =

     <sect1 id=3D"Contributing-Code-Back-to-the-OpenMCL-Project">
-      <para>Contributing Code Back to the OpenMCL Project
-This section is a placeholder, added as of August 2004.  The
-full text is being written, and will be added as soon as it is
-available.</para>
+      <title>Contributing Code Back to the OpenMCL Project</title>
+      <para>This section is a placeholder, added as of August 2004.  The
+      full text is being written, and will be added as soon as it is
+      available.</para>
     </sect1>
 =

     <sect1 id=3D"Using-OpenMCL-in--development--and-in--user--mode">
-      <para>Using OpenMCL in "development" and in  "user" mode
-As it's distributed, OpenMCL starts up with *PACKAGE* set to the CL-USER
-package and with most predefined functions and methods protected against
-accidental redefinition.  The package setting is of course a requirement
-of ANSI CL, while the protection protection is intended to catch certain
-types of programming errors (accidentally redefining a CL or CCL function)
-before those errors have a chance to do much damage.</para>
-      <para>These settings may make using OpenMCL to develop OpenMCL a bit=
 more
-awkward, since much of that process assumes that the CCL package is
-current (and a primary purpose of that process is to redefine some
-"predefined, builtin functions".) The standard, "routine"
-ways of building OpenMCL from sources (see )
-- COMPILE-CCL, XCOMPILE-CCL, and XLOAD-LEVEL-0 - bind *PACKAGE* to the
-"CCL" package and enable the redefinition of predefined functions;
-the symbols COMPILE-CCL, XCOMPILE-CCL, and XLOAD-LEVEL-0 are additionally
-now exported from the "CCL" package.</para>
-      <para>Some other (more ad-hoc) ways of doing development on OpenMCL -
-compiling and/or loading individual files, incrementally redefining
-individual functions - may be awkward unless one reverts to the mode of
-operation which was traditionally offered in OpenMCL. (Some OpenMCL source
-files - especially those that comprise the bootstrapping image sources and
-the first few files in the "cold load" sequence - are compiled and
-loaded in the "CCL" package but don't contain (IN-PACKAGE
-"CCL") forms, since IN-PACKAGE doesn't work until later in the
-cold load sequence.)</para>
-      <para>The somewhat bizarre behavior of both SET-USER-ENVIRONMENT and
-SET-DEVELOPMENT-ENVIRONMENT with respect to the special variables they
-affect is intended to allow those constructs to take effect when the
-read-eval-print loop next returns to a top-level '? ' prompt;
-the constructs can meaningfully be used inside LOAD, for instance
-(recall that LOAD binds *PACKAGE*), though using both constructs within
-the same LOAD call would likely be pretty confusing.</para>
-      <para>"user" and "development" are otherwise very
-generic terms; here they're intended to enforce the distinction
-between "using" OpenMCL and "developing" it.</para>
-      <para>The initial environment from which OpenMCL images are saved is=
 one
-where (SET-USER-ENVIRONMENT T) has just been called; in previous
-versions, it was effectively as if (SET-DEVELOPMENT-ENVIRONMENT T) had
-just been called.</para>
-      <para>Hopefully, most users of OpenMCL can safely ignore these issues
-most of the time. Note that doing (SET-USER-ENVIRONMENT T) after loading
-one's own code (or 3rd-party code) into OpenMCL would protect that
-code (as well as OpenMCL's) from accidental redefinition; that may
-be useful in some cases.</para>
+      <title>Using OpenMCL in "development" and in  "user" mode</title>
+
+      <para>As it's distributed, OpenMCL starts up with *PACKAGE* set
+      to the CL-USER package and with most predefined functions and
+      methods protected against accidental redefinition.  The package
+      setting is of course a requirement of ANSI CL, while the
+      protection protection is intended to catch certain types of
+      programming errors (accidentally redefining a CL or CCL
+      function) before those errors have a chance to do much
+      damage.</para>
+      <para>These settings may make using OpenMCL to develop OpenMCL a
+      bit more awkward, since much of that process assumes that the
+      CCL package is current (and a primary purpose of that process is
+      to redefine some "predefined, builtin functions".) The standard,
+      "routine" ways of building OpenMCL from sources (see ) -
+      COMPILE-CCL, XCOMPILE-CCL, and XLOAD-LEVEL-0 - bind *PACKAGE* to
+      the "CCL" package and enable the redefinition of predefined
+      functions; the symbols COMPILE-CCL, XCOMPILE-CCL, and
+      XLOAD-LEVEL-0 are additionally now exported from the "CCL"
+      package.</para>
+      <para>Some other (more ad-hoc) ways of doing development on
+      OpenMCL - compiling and/or loading individual files,
+      incrementally redefining individual functions - may be awkward
+      unless one reverts to the mode of operation which was
+      traditionally offered in OpenMCL. (Some OpenMCL source files -
+      especially those that comprise the bootstrapping image sources
+      and the first few files in the "cold load" sequence - are
+      compiled and loaded in the "CCL" package but don't contain
+      (IN-PACKAGE "CCL") forms, since IN-PACKAGE doesn't work until
+      later in the cold load sequence.)</para>
+      <para>The somewhat bizarre behavior of both SET-USER-ENVIRONMENT
+      and SET-DEVELOPMENT-ENVIRONMENT with respect to the special
+      variables they affect is intended to allow those constructs to
+      take effect when the read-eval-print loop next returns to a
+      top-level '? ' prompt; the constructs can meaningfully be used
+      inside LOAD, for instance (recall that LOAD binds *PACKAGE*),
+      though using both constructs within the same LOAD call would
+      likely be pretty confusing.</para>
+      <para>"user" and "development" are otherwise very generic terms;
+      here they're intended to enforce the distinction between "using"
+      OpenMCL and "developing" it.</para>
+      <para>The initial environment from which OpenMCL images are
+      saved is one where (SET-USER-ENVIRONMENT T) has just been
+      called; in previous versions, it was effectively as if
+      (SET-DEVELOPMENT-ENVIRONMENT T) had just been called.</para>
+      <para>Hopefully, most users of OpenMCL can safely ignore these
+      issues most of the time. Note that doing (SET-USER-ENVIRONMENT
+      T) after loading one's own code (or 3rd-party code) into OpenMCL
+      would protect that code (as well as OpenMCL's) from accidental
+      redefinition; that may be useful in some cases.</para>
     </sect1>
 =

     <sect1 id=3D"Debugging-facilities-in-the-lisp-kernel">
-      <para>Debugging facilities in the lisp kernel
-In a perfect world, something like this couldn't happen:</para>
+      <title>Debugging facilities in the lisp kernel</title>
+      <para> In a perfect world, something like this couldn't
+      happen:</para>
       <programlisting>
 Welcome to OpenMCL Version x.y!
 ? (defun foo (x)
@@ -10735,7 +15218,7 @@
 =

 ? (foo -1) ;Oops. Too late ...
 Unhandled exception 11 at 0x300e90c8, context->regs at #x7ffff6b8
-Continue/Debugger/eXit <enter>?
+Continue/Debugger/eXit &lt;enter&gt;?
 </programlisting>
       <para>As you may have noticed, it's not a perfect world; it's rare
 that the cause (attempting to reference the CDR of -1, and therefore
@@ -10749,8 +15232,8 @@
 deliberately:</para>
       <programlisting>
 ? (defun classify (n)
-     (cond ((> n 0) "Greater")
-           ((< n 0) "Less")
+     (cond ((&gt; n 0) "Greater")
+           ((&lt; n 0) "Less")
            (t
             ;;; Sheesh ! What else could it be ?
             (ccl::bug "I give up. How could this happen ?"))))
@@ -10761,40 +15244,44 @@
 I give up. How could this happen ?
 ? for help
 [12345] OpenMCL kernel debugger:
-</programlisting>
-      <para>CCL::BUG isn't quite the right tool for this example (a call to
-BREAK or PRINT might do a better job of clearing up the mystery), but
-it's sometimes helpful when those other tools can't be used.
-The
-lisp error system notices, for instance, if attempts to signal errors
-themselves cause errors to be signaled; this sort of thing can happen if
-CLOS or the I/O system are broken or missing. After some small number of
-recursive errors, the error system gives up and calls CCL::BUG.</para>
-      <para>If one enters a '?' at the kernel debugger prompt, one will se=
e output
-like:</para>
-      <programlisting>(S)  Find and describe symbol matching specified name
+      </programlisting>
+      <para>CCL::BUG isn't quite the right tool for this example (a
+      call to BREAK or PRINT might do a better job of clearing up the
+      mystery), but it's sometimes helpful when those other tools
+      can't be used.  The lisp error system notices, for instance, if
+      attempts to signal errors themselves cause errors to be
+      signaled; this sort of thing can happen if CLOS or the I/O
+      system are broken or missing. After some small number of
+      recursive errors, the error system gives up and calls
+      CCL::BUG.</para>
+      <para>If one enters a '?' at the kernel debugger prompt, one
+      will see output like:</para>
+      <programlisting>
+(S)  Find and describe symbol matching specified name
 (B)  Show backtrace
 (X)  Exit from this debugger, asserting that any exception was handled
 (K)  Kill OpenMCL process
 (?)  Show this help
 </programlisting>
-      <para>CCL::BUG just does an FF-CALL into the lisp kernel.  If the ke=
rnel debugger
-was invoked because of an unhandled exception (such as an illegal memory
-reference) the OS kernel saves the machine state
-("context") in a data structure for us, and in that case some additional
-options can be used to display the contents of the registers at the point
-of the exception. Another function - CCL::DBG - causes a special exception
-to be generated and enters the lisp kernel debugger with a non-null
-"context":</para>
-      <programlisting>? (defun classify2 (n)
-  (cond ((> n 0) "Greater")
-        ((< n 0) "Less")
+      <para>CCL::BUG just does an FF-CALL into the lisp kernel.  If
+      the kernel debugger was invoked because of an unhandled
+      exception (such as an illegal memory reference) the OS kernel
+      saves the machine state ("context") in a data structure for us,
+      and in that case some additional options can be used to display
+      the contents of the registers at the point of the
+      exception. Another function - CCL::DBG - causes a special
+      exception to be generated and enters the lisp kernel debugger
+      with a non-null "context":</para>
+      <programlisting>
+? (defun classify2 (n)
+  (cond ((&gt; n 0) "Greater")
+        ((&lt; n 0) "Less")
         (t (dbg n))))
 CLASSIFY2
 =

 ? (classify2 0)
 Lisp Breakpoint
- While executing: #<Function CLASSIFY2 #x08476cfe>
+ While executing: #&lt;Function CLASSIFY2 #x08476cfe>
 ? for help
 [12345] OpenMCL kernel debugger: ?
 (G)  Set specified GPR to new value
@@ -10816,18 +15303,18 @@
 we'd see a dislay like:</para>
       <programlisting>rnil =3D 0x01836015
 nargs =3D 0
-r16 (fn) =3D #<Function CLASSIFY2 #x30379386>
+r16 (fn) =3D #&lt;Function CLASSIFY2 #x30379386>
 r23 (arg_z) =3D 0
 r22 (arg_y) =3D 0
 r21 (arg_x) =3D 0
-r20 (temp0) =3D #<26-element vector subtag =3D 2F @#x303793ee>
+r20 (temp0) =3D #&lt;26-element vector subtag =3D 2F @#x303793ee>
 r19 (temp1/next_method_context) =3D 6393788
-r18 (temp2/nfn) =3D #<Function CLASSIFY2 #x30379386>
+r18 (temp2/nfn) =3D #&lt;Function CLASSIFY2 #x30379386>
 r17 (temp3/fname) =3D CLASSIFY2
 r31 (save0) =3D 0
 r30 (save1) =3D *TERMINAL-IO*
 r29 (save2) =3D 0
-r28 (save3) =3D (#<RESTART @#x01867f2e> #<RESTART @#x01867f56>)
+r28 (save3) =3D (#&lt;RESTART @#x01867f2e> #&lt;RESTART @#x01867f56>)
 r27 (save4) =3D ()
 r26 (save5) =3D ()
 r25 (save6) =3D ()
@@ -10846,46 +15333,49 @@
     </sect1>
 =

     <sect1 id=3D"Using-AltiVec-in-OpenMCL-LAP-functions">
-      <para>Using AltiVec in OpenMCL LAP functions</para>
+      <title>Using AltiVec in OpenMCL LAP functions</title>
 =

       <sect2 id=3D"Overview--16-">
-        <para>Overview
-It's now possible to use AltiVec instructions in PPC LAP
-(assembler) functions.</para>
-        <para>The lisp kernel detects the presence or absence of AltiVec a=
nd
-preserves AltiVec state on lisp thread switch and in response to
-exceptions, but the implementation doesn't otherwise use vector
-operations.</para>
-        <para>This document doesn't document PPC LAP programming in genera=
l.
-Ideally, there would be some document that did.</para>
-        <para>This document does explain AltiVec register-usage convention=
s in
-OpenMCL and explains the use of some lap macros that help to enforce those
-conventions.</para>
-        <para>All of the global symbols described below are exported from =
the CCL
-package. Note that lap macro names, ppc instruction names, and (in most
-cases) register names are treated as strings, so this only applies to
-functions and global variable names.</para>
-        <para>Much of the OpenMCL support for AltiVec LAP programming is b=
ased on
-work contributed to MCL by Shannon Spires.</para>
+	<title>Overview</title>
+        <para>It's now possible to use AltiVec instructions in PPC LAP
+        (assembler) functions.</para>
+        <para>The lisp kernel detects the presence or absence of
+        AltiVec and preserves AltiVec state on lisp thread switch and
+        in response to exceptions, but the implementation doesn't
+        otherwise use vector operations.</para>
+        <para>This document doesn't document PPC LAP programming in
+        general.  Ideally, there would be some document that
+        did.</para>
+        <para>This document does explain AltiVec register-usage
+        conventions in OpenMCL and explains the use of some lap macros
+        that help to enforce those conventions.</para>
+        <para>All of the global symbols described below are exported
+        from the CCL package. Note that lap macro names, ppc
+        instruction names, and (in most cases) register names are
+        treated as strings, so this only applies to functions and
+        global variable names.</para>
+        <para>Much of the OpenMCL support for AltiVec LAP programming
+        is based on work contributed to MCL by Shannon Spires.</para>
       </sect2>
 =

       <sect2 id=3D"Register-usage-conventions">
-        <para>Register usage conventions
-OpenMCL LAP functions that use AltiVec instructions must
-interoperate with each other and with C functions; that suggests that they
-follow C AltiVec register usage conventions. (vr0-vr1 scratch, vr2-vr13
-parameters/return value, vr14-vr19 temporaries, vr20-vr31 callee-save
-non-volatile registers.)</para>
-        <para>The EABI (Embedded Application Binary Interface) used in Lin=
uxPPC
-doesn't ascribe particular significance to the vrsave special-purpose
-register; on other platforms (notably MacOS), it's used as a bitmap
-which indicates to system-level code which vector registers contain
-meaningful values.</para>
-        <para>The WITH-ALTIVEC-REGISTERS lapmacro generates code which whi=
ch
-saves, updates, and restores VRSAVE on platforms where this is required
-(as indicated by the value of the special variable which controls this)
-and ignores VRSAVE on platforms that don't require it to be
-maintained.</para>
+	<title>Register usage conventions</title>
+        <para>OpenMCL LAP functions that use AltiVec instructions must
+        interoperate with each other and with C functions; that
+        suggests that they follow C AltiVec register usage
+        conventions. (vr0-vr1 scratch, vr2-vr13 parameters/return
+        value, vr14-vr19 temporaries, vr20-vr31 callee-save
+        non-volatile registers.)</para>
+        <para>The EABI (Embedded Application Binary Interface) used in
+        LinuxPPC doesn't ascribe particular significance to the vrsave
+        special-purpose register; on other platforms (notably MacOS),
+        it's used as a bitmap which indicates to system-level code
+        which vector registers contain meaningful values.</para>
+        <para>The WITH-ALTIVEC-REGISTERS lapmacro generates code which
+        which saves, updates, and restores VRSAVE on platforms where
+        this is required (as indicated by the value of the special
+        variable which controls this) and ignores VRSAVE on platforms
+        that don't require it to be maintained.</para>
         <para>On all PPC platforms, it's necessary to save any non-volatile
 vector registers (vr20 .. vr31) before assigning to them and to restore
 such registers before returning to the caller.</para>
@@ -10931,441 +15421,263 @@
     </sect1>
 =

     <sect1 id=3D"Development-Mode-Dictionary">
-      <para>Development-Mode Dictionary</para>
-
-      <sect2 id=3D"iWARN-IF-REDEFINE-KERNEL-">
-        <para>*WARN-IF-REDEFINE-KERNEL*</para>
-        <informalfigure>*warn-if-redefine-kernel</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>*WARN-IF-REDEFINE-KERNEL* &mdash;</para>
-        <para>Variable</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>When true, attempts to redefine (via DEFUN or DEFMETHOD)
-functions and methods that are marked as being
-"predefined" signal continuable errors.</para>
-        <para>Note that these are CERRORs, not warnings, and that
-no lisp functions or methods have been defined in the kernel
-in MCL or OpenMCL since 1987 or so.</para>
-      </sect2>
-
-      <sect2 id=3D"SET-DEVELOPMENT-ENVIRONMENT">
-        <para>SET-DEVELOPMENT-ENVIRONMENT</para>
-        <informalfigure>set-development-environment</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SET-DEVELOPMENT-ENVIRONMENT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-set-development-environment
-	  &amp;optional
-	  unmark-builtin-functions
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Arranges that the outermost special bindings of *PACKAGE*
-and *WARN-IF-REDEFINE-KERNEL* restore values of the "CCL"
-package and NIL to these variables, respectively. If the optional
-argument is true, marks all globally defined functions and methods
-as being "not predefined" (this is a fairly expensive
-operation.)</para>
-      </sect2>
-
-      <sect2 id=3D"SET-USER-ENVIRONMENT">
-        <para>SET-USER-ENVIRONMENT</para>
-        <informalfigure>set-user-environment</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>SET-USER-ENVIRONMENT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-set-user-environment
-	  &amp;optional mark-builtin-functions
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Arranges that the outermost special bindings of *PACKAGE*
-and *WARN-IF-REDEFINE-KERNEL* restore values of the
-"CL-USER" package and T to these variables, respectively.
-If the optional argument is true, marks all globally defined
-functions and methods as being "predefined" (this is a
-fairly expensive operation.)</para>
-      </sect2>
-
-      <sect2 id=3D"iALTIVEC-AVAILABLE-">
-        <para>*ALTIVEC-AVAILABLE*</para>
-        <informalfigure>*altivec-available*</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>*ALTIVEC-AVAILABLE* &mdash;</para>
-        <para>Variable</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>This variable is intitialized each time an OpenMCL session
-starts based on information provided by the lisp kernel. Its value
-is true if AltiVec is present and false otherwise. This variable
-shouldn't be set by user code.</para>
-      </sect2>
-
-      <sect2 id=3D"ALTIVEC-AVAILABLE-P">
-        <para>ALTIVEC-AVAILABLE-P</para>
-        <informalfigure>altivec-available-p</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>ALTIVEC-AVAILABLE-P &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-altivec-available-p
-</programlisting>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Returns non-NIL if AltiVec is available.</para>
-      </sect2>
-
-      <sect2 id=3D"iALTIVEC-LAPMACROS-MAINTAIN-VRSAVE-P-">
-        <para>*ALTIVEC-LAPMACROS-MAINTAIN-VRSAVE-P*</para>
-        <informalfigure>*altivec-lapmacros-maintain-vrsave-p*</informalfig=
ure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>*ALTIVEC-LAPMACROS-MAINTAIN-VRSAVE-P* &mdash;</para>
-        <para>Variable</para>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Intended to control the expansion of certain lap macros.
-Initialized to NIL on LinuxPPC; initialized to T on platforms
-(such as MacOS X/Darwin) that require that the VRSAVE SPR contain
-a bitmask of active vector registers at all times.</para>
-      </sect2>
-
-      <sect2 id=3D"WITH-ALTIVEC-REGISTERS">
-        <para>WITH-ALTIVEC-REGISTERS</para>
-        <informalfigure>with-altivec-registers</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>WITH-ALTIVEC-REGISTERS &mdash;</para>
-        <para>LAP Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-with-altivec-registers
-	  reglist &amp;body body
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>reglist
-            <variablelist>A list of vector register names (vr0 .. vr31).</=
variablelist>
-          </indexterm><indexterm>body
-            <variablelist>A sequence of PPC LAP instructions.</variablelis=
t>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Specifies the set of AltiVec registers used in body. If
-*altivec-lapmacros-maintain-vrsave-p* is true when the macro is
-expanded, generates code to save the VRSAVE SPR and updates VRSAVE
-to incude a bitmask generated from the specified register list.
-Generates code which saves any non-volatile vector registers which
-appear in the register list, executes body, and restores the saved
-non-volatile vector registers (and, if
-*altivec-lapmacros-maintain-vrsave-p* is true, restores VRSAVE as
-well. Uses the IMM0 register (r3) as a temporary.</para>
-      </sect2>
-
-      <sect2 id=3D"WITH-VECTOR-BUFFER">
-        <para>WITH-VECTOR-BUFFER</para>
-        <informalfigure>with-vector-buffer</informalfigure>
-        <bridgehead renderas=3D"sect3">Name</bridgehead>
-        <para>WITH-VECTOR-BUFFER &mdash;</para>
-        <para>LAP Macro</para>
-        <bridgehead renderas=3D"sect3">Synopsis</bridgehead>
-        <programlisting>
-with-vector-buffer base n &amp;body body
-</programlisting>
-        <bridgehead renderas=3D"sect3">Arguments and Values</bridgehead>
-        <term><indexterm>base
-            <variablelist>Any available general-purpose register.</variabl=
elist>
-          </indexterm><indexterm>n
-            <variablelist>An integer between 1 and 254, inclusive. (Should=
typically be much, much closer to 1.) Specifies the size ofthe buffer, in 1=
6-byte units.</variablelist>
-          </indexterm><indexterm>body
-            <variablelist>A sequence of PPC LAP instructions.</variablelis=
t>
-          </indexterm>
-        </term>
-        <bridgehead renderas=3D"sect3">Description</bridgehead>
-        <para>Generates code which allocates a 16-byte aligned buffer
-large enough to contain N vector registers; the GPR base points to
-the lowest address of this buffer. After processing body, the
-buffer will be deallocated. The body should preserve the value of
-base as long as it needs to reference the buffer. It's
-intended that base be used as a base register in stvx and lvx
-instructions within the body.</para>
-      </sect2>
+      <title>Development-Mode Dictionary</title>
+
+      <refentry id=3D"v_warn-if-redefine-kernel">
+	<indexterm zone=3D"v_warn-if-redefine-kernel">
+	  <primary>*warn-if-redefine-kernel</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>*WARN-IF-REDEFINE-KERNEL*</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Variable</refclass>
+	</refnamediv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>When true, attempts to redefine (via DEFUN or DEFMETHOD)
+	  functions and methods that are marked as being
+	  &#34;predefined&#34; signal continuable errors.</para>
+
+	  <para>Note that these are CERRORs, not warnings, and that
+	  no lisp functions or methods have been defined in the kernel
+	  in MCL or OpenMCL since 1987 or so.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_set-development-environment">
+	<indexterm zone=3D"f_set-development-environment">
+	  <primary>set-development-environment</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>SET-DEVELOPMENT-ENVIRONMENT</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>set-development-environment</function>
+	  &optional;
+	  unmark-builtin-functions</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Arranges that the outermost special bindings of *PACKAGE*
+	  and *WARN-IF-REDEFINE-KERNEL* restore values of the &#34;CCL&#34;
+	  package and NIL to these variables, respectively. If the optional
+	  argument is true, marks all globally defined functions and methods
+	  as being &#34;not predefined&#34; (this is a fairly expensive
+	  operation.)</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_set-user-environment">
+	<indexterm zone=3D"f_set-user-environment">
+	  <primary>set-user-environment</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>SET-USER-ENVIRONMENT</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>set-user-environment</function>
+	  &optional; mark-builtin-functions</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Arranges that the outermost special bindings of *PACKAGE*
+	  and *WARN-IF-REDEFINE-KERNEL* restore values of the
+	  &#34;CL-USER&#34; package and T to these variables, respectively.
+	  If the optional argument is true, marks all globally defined
+	  functions and methods as being &#34;predefined&#34; (this is a
+	  fairly expensive operation.)</para>
+	</refsect1>
+      </refentry>
+      <refentry id=3D"v_altivec-available">
+	<indexterm zone=3D"v_altivec-available">
+	  <primary>*altivec-available*</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>*ALTIVEC-AVAILABLE*</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Variable</refclass>
+	</refnamediv>
+
+	<refsect1>
+	  <title>Description</title>
+	  <para>This variable is intitialized each time an OpenMCL session
+	  starts based on information provided by the lisp kernel. Its value
+	  is true if AltiVec is present and false otherwise. This variable
+	  shouldn't be set by user code.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"f_altivec-available-p">
+	<indexterm zone=3D"f_altivec-available-p">
+	  <primary>altivec-available-p</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>ALTIVEC-AVAILABLE-P</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+	=

+	<refsynopsisdiv>
+	  <synopsis><function>altivec-available-p</function></synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Returns non-NIL if AltiVec is available.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"v_altivec-lapmacros-maintain-vrsave-p">
+	<indexterm zone=3D"v_altivec-lapmacros-maintain-vrsave-p">
+	  <primary>*altivec-lapmacros-maintain-vrsave-p*</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>*ALTIVEC-LAPMACROS-MAINTAIN-VRSAVE-P*</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Variable</refclass>
+	</refnamediv>
+	=

+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Intended to control the expansion of certain lap macros.
+	  Initialized to NIL on LinuxPPC; initialized to T on platforms
+	  (such as MacOS X/Darwin) that require that the VRSAVE SPR contain
+	  a bitmask of active vector registers at all times.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"lapm_with-altivec-registers">
+	<indexterm zone=3D"lapm_with-altivec-registers">
+	  <primary>with-altivec-registers</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>WITH-ALTIVEC-REGISTERS</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>LAP Macro</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>with-altivec-registers</function>
+	  reglist &body; body</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>reglist</term>
+
+	      <listitem>
+		<para>A list of vector register names (vr0 .. vr31).</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>body</term>
+
+	      <listitem>
+		<para>A sequence of PPC LAP instructions.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+
+	  <para>Specifies the set of AltiVec registers used in body. If
+	  *altivec-lapmacros-maintain-vrsave-p* is true when the macro is
+	  expanded, generates code to save the VRSAVE SPR and updates VRSAVE
+	  to incude a bitmask generated from the specified register list.
+	  Generates code which saves any non-volatile vector registers which
+	  appear in the register list, executes body, and restores the saved
+	  non-volatile vector registers (and, if
+	  *altivec-lapmacros-maintain-vrsave-p* is true, restores VRSAVE as
+	  well. Uses the IMM0 register (r3) as a temporary.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id=3D"lapm_with-vector-buffer">
+	<indexterm zone=3D"lapm_with-vector-buffer">
+	  <primary>with-vector-buffer</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>WITH-VECTOR-BUFFER</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>LAP Macro</refclass>
+	</refnamediv>
+	=

+	<refsynopsisdiv>
+	  <synopsis>with-vector-buffer base n &body; body</synopsis>
+	</refsynopsisdiv>
+
+	<refsect1>
+	  <title>Arguments and Values</title>
+
+	  <variablelist>
+	    <varlistentry>
+	      <term>base</term>
+
+	      <listitem>
+		<para>Any available general-purpose register.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>n</term>
+
+	      <listitem>
+		<para>An integer between 1 and 254, inclusive. (Should
+		typically be much, much closer to 1.) Specifies the size of
+		the buffer, in 16-byte units.</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry>
+	      <term>body</term>
+
+	      <listitem>
+		<para>A sequence of PPC LAP instructions.</para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Description</title>
+	  <para>Generates code which allocates a 16-byte aligned buffer
+	  large enough to contain N vector registers; the GPR base points to
+	  the lowest address of this buffer. After processing body, the
+	  buffer will be deallocated. The body should preserve the value of
+	  base as long as it needs to reference the buffer. It's
+	  intended that base be used as a base register in stvx and lvx
+	  instructions within the body.</para>
+	</refsect1>
+      </refentry>
     </sect1>
-  </chapter> <para>Symbol Index
-<tgroup>
-  <secondaryie>
-    <indexdiv>#_, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>%ff-call, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>%reference-external-entry-point, see </indexdiv></secondaryi=
e>
-  <secondaryie>
-    <indexdiv>*alternate-line-terminator*, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>*altivec-available*, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>*altivec-lapmacros-maintain-vrsave-p*, see </indexdiv></seco=
ndaryie>
-  <secondaryie>
-    <indexdiv>*current-process*, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>*default-external-format*, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>*ticks-per-second*, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>*warn-if-redefine-kernel, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>:external-format, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>:y, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>@class, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>@selector, see </indexdiv></secondaryie></tgroup>
-<tgroup>A
-  <secondaryie>
-    <indexdiv>accept-connection, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>all-processes, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>altivec-available-p, see </indexdiv></secondaryie></tgroup>
-<tgroup>C
-  <secondaryie>
-    <indexdiv>close, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>close-shared-library, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>configure-egc, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>current-directory-name, see </indexdiv></secondaryie></tgrou=
p>
-<tgroup>D
-  <secondaryie>
-    <indexdiv>def-foreign-type, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>defcallback, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>define-objc-class-method, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>define-objc-method, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>dotted-to-ipaddr, see </indexdiv></secondaryie></tgroup>
-<tgroup>E
-  <secondaryie>
-    <indexdiv>egc, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>egc-active-p, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>egc-configuration, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>egc-enabled-p, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>external, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>external-call, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>external-process-error-stream, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>external-process-id, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>external-process-input-stream, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>external-process-output-stream, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>external-process-status, see </indexdiv></secondaryie></tgro=
up>
-<tgroup>F
-  <secondaryie>
-    <indexdiv>ff-call, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>foreign-symbol-address, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>foreign-symbol-entry, see </indexdiv></secondaryie></tgroup>
-<tgroup>G
-  <secondaryie>
-    <indexdiv>gc-retain-pages, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>gc-retaining-pages, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>get-user-home-dir, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>getenv, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>getpid, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>getuid, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>grab-lock, see </indexdiv></secondaryie></tgroup>
-<tgroup>I
-  <secondaryie>
-    <indexdiv>ipaddr-to-dotted, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>ipaddr-to-hostname, see </indexdiv></secondaryie></tgroup>
-<tgroup>L
-  <secondaryie>
-    <indexdiv>lisp-heap-gc-threshold, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>local-host, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>local-port, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>lookup-hostname, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>lookup-port, see </indexdiv></secondaryie></tgroup>
-<tgroup>M
-  <secondaryie>
-    <indexdiv>make-lock, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>make-process, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>make-read-write-lock, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>make-record, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>make-semaphore, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>make-socket, see </indexdiv></secondaryie></tgroup>
-<tgroup>N
-  <secondaryie>
-    <indexdiv>ns-lisp-string, see </indexdiv></secondaryie></tgroup>
-<tgroup>O
-  <secondaryie>
-    <indexdiv>open-shared-library, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>os-command, see </indexdiv></secondaryie></tgroup>
-<tgroup>P
-  <secondaryie>
-    <indexdiv>pref, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-abort, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-allow-schedule, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-enable, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-input-wait, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-interrupt, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-kill, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-output-wait, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-preset, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-reset, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-resume, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-run-function, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-suspend, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-suspend-count, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-wait, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-wait-with-timeout, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>process-whostate, see </indexdiv></secondaryie></tgroup>
-<tgroup>R
-  <secondaryie>
-    <indexdiv>receive-from, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>release-lock, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>remote-host, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>remote-port, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>request-terminal-input-via-break, see </indexdiv></secondary=
ie>
-  <secondaryie>
-    <indexdiv>rlet, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>rletz, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>run-program, see </indexdiv></secondaryie></tgroup>
-<tgroup>S
-  <secondaryie>
-    <indexdiv>send-to, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>set-development-environment, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>set-lisp-heap-gc-threshold, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>set-user-environment, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>setenv, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>setgid, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>setuid, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>SHARP-AMPERSAND, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>shutdown, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>signal-external-process, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>signal-semaphore, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>socket-address-family, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>socket-connect, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>socket-error, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>socket-error-code, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>socket-error-identifier, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>socket-error-situation, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>socket-format, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>socket-os-fd, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>socket-type, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>stream-device, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>stream-read-ivector, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>stream-read-list, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>stream-read-vector, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>stream-write-ivector, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>stream-write-list, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>stream-write-vector, see </indexdiv></secondaryie></tgroup>
-<tgroup>T
-  <secondaryie>
-    <indexdiv>terminate-when-unreachable, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>timed-wait-on-semaphore, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>try-lock, see </indexdiv></secondaryie></tgroup>
-<tgroup>U
-  <secondaryie>
-    <indexdiv>unuse-interface-dir, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>use-interface-dir, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>use-lisp-heap-gc-threshold, see </indexdiv></secondaryie></t=
group>
-<tgroup>W
-  <secondaryie>
-    <indexdiv>wait-on-semaphore, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>with-altivec-registers, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>with-lock-grabbed, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>with-open-socket, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>with-read-lock, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>with-terminal-input, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>with-vector-buffer, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>with-write-lock, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>without-interrupts, see </indexdiv></secondaryie></tgroup></=
para>
+  </chapter>
+  <index><title>Symbol Index</title></index>
 </book>
-



More information about the Openmcl-cvs-notifications mailing list