Index: /trunk/source/doc/src/openmcl-documentation.xml
===================================================================
--- /trunk/source/doc/src/openmcl-documentation.xml	(revision 8519)
+++ /trunk/source/doc/src/openmcl-documentation.xml	(revision 8520)
@@ -1,11 +1,10 @@
 <?xml version="1.0" encoding="US-ASCII"?>
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-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="en">
@@ -1074,8 +1073,8 @@
         <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>
@@ -1292,5 +1291,5 @@
       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
@@ -1476,5 +1475,5 @@
 
 ? (process-run-function "sleeper" #'(lambda () (sleep 5) (break "broken")))
-#<PROCESS sleeper(1) [Enabled] #x3063B33E&gt;
+#&lt;PROCESS sleeper(1) [Enabled] #x3063B33E&gt;
 
 ?
@@ -1495,9 +1494,9 @@
 ;;
 > 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
@@ -1523,8 +1522,8 @@
 
 ? (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;
 
 ? ;;
@@ -1602,5 +1601,6 @@
 
     <sect1 id="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>
@@ -1723,5 +1723,4 @@
     <sect1 id="Threads-Dictionary">
       <title>Threads Dictionary</title>
-
       <refentry id="f_all-processes">
 	<indexterm zone="f_all-processes">
@@ -1759,9 +1758,9 @@
 
 	  <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>
@@ -1777,6 +1776,5 @@
       </refentry>
 
-
-       <refentry id="f_make-process">
+      <refentry id="f_make-process">
 	<indexterm zone="f_make-process">
 	  <primary>make-process</primary>
@@ -1945,1185 +1943,2442 @@
       </refentry>
 
-      <sect2 id="PROCESS-SUSPEND">
-        <para>PROCESS-SUSPEND</para>
-        <informalfigure>process-suspend</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PROCESS-SUSPEND &mdash; Suspends a specified process.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-suspend process
-	  => result
-</programlisting>
-        <bridgehead renderas="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 runnableand is now suspended; NIL otherwise.  That is, T if<literal>process</literal>'stransitioned from 0 to 1.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">,</para>
-        <bridgehead renderas="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="PROCESS-RESUME">
-        <para>PROCESS-RESUME</para>
-        <informalfigure>process-resume</informalfigure>
-        <bridgehead renderas="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="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-resume process
-	  => result
-</programlisting>
-        <bridgehead renderas="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 suspendedand is now runnable; NIL otherwise.  That is, T if<literal>process</literal>'stransitioned from  to 0.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">,</para>
-        <bridgehead renderas="sect3">Notes</bridgehead>
-        <para>This was previously called PROCESS-ENABLE;
- now does something slightly
-different.</para>
-      </sect2>
-
-      <sect2 id="PROCESS-SUSPEND-COUNT">
-        <para>PROCESS-SUSPEND-COUNT</para>
-        <informalfigure>process-suspend-count</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PROCESS-SUSPEND-COUNT &mdash; Returns the number of currently-pending suspensions
-applicable to a given process.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    process-suspend-count
+      <refentry id="f_process-suspend">
+	<indexterm zone="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
+	  => 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="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="f_process-resume"/>
+	  before <varname>process</varname> is able to run.  What
+	  <function>process-suspend</function> actually does is increment
+	  the <xref linkend="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="inline">
+	    <member><xref linkend="f_process-resume"/></member>
+	    <member><xref linkend="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="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="f_process-resume">
+	<indexterm zone="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
+	  => 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="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="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="f_process-suspend-count"/> of
+	  <varname>process</varname>, to a minimum of 0.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 
+	  <simplelist type="inline">
+	    <member><xref linkend="f_process-suspend"/></member>
+	    <member><xref linkend="f_process-suspend-count"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>
+	    This was previously called PROCESS-ENABLE;
+	    <xref linkend="f_process-enable"/> now does something slightly
+	    different.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_process-suspend-count">
+	<indexterm zone="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 => result
-
-</programlisting>
-        <bridgehead renderas="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>process</literal>, or NIL if<literal>process</literal> has expired.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">,</para>
-      </sect2>
-
-      <sect2 id="PROCESS-PRESET">
-        <para>PROCESS-PRESET</para>
-        <informalfigure>process-preset</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PROCESS-PRESET &mdash; Sets the initial function and arguments of a specified
-process.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-preset
-	  process function &amp;rest args
-	  => result
-</programlisting>
-        <bridgehead renderas="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 symbolwhich names it.</variablelist>
-          </indexterm><indexterm>args
-            <variablelist>a list of values, appropriate as arguments to<literal>function</literal>.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>undefined.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, ,</para>
-      </sect2>
-
-      <sect2 id="PROCESS-ENABLE">
-        <para>PROCESS-ENABLE</para>
-        <informalfigure>process-enable</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PROCESS-ENABLE &mdash; Begins executing the initial function of a specified
-process.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-enable
-	  process &amp;optional timeout
-
-</programlisting>
-        <bridgehead renderas="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-negative 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="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.</para>
-        <bridgehead renderas="sect3">See Also</bridgehead>
-        <para role="continues">, ,</para>
-        <bridgehead renderas="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="PROCESS-RUN-FUNCTION">
-        <para>PROCESS-RUN-FUNCTION</para>
-        <informalfigure>process-run-function</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PROCESS-RUN-FUNCTION &mdash; Creates a process, presets it, and enables it.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-run-function
-	  process-specifier function &amp;rest args => process
-</programlisting>
-        <term><indexterm>process-specifier
-            <variablelist><literal>name</literal> |(<literal>&amp;key</literal> <literal>name</literal><literal>persistent</literal><literal>priority</literal><literal>class</literal><literal>stack-size</literal><literal>vstack-size</literal><literal>tstack-size</literal>)</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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 symbolwhich names it.  Passed to<literal>preset-process</literal>.</variablelist>
-          </indexterm><indexterm>persistent
-            <variablelist>a boolean, passed to <literal>make-process</literal>.</variablelist>
-          </indexterm><indexterm>priority
-            <variablelist>ignored.</variablelist>
-          </indexterm><indexterm>class
-            <variablelist>a subclass of CCL:PROCESS.  Passed to<literal>make-process</literal>.</variablelist>
-          </indexterm><indexterm>stack-size
-            <variablelist>a size, in bytes.  Passed to<literal>make-process</literal>.</variablelist>
-          </indexterm><indexterm>vstack-size
-            <variablelist>a size, in bytes.  Passed to<literal>make-process</literal>.</variablelist>
-          </indexterm><indexterm>tstack-size
-            <variablelist>a size, in bytes.  Passed to<literal>make-process</literal>.</variablelist>
-          </indexterm><indexterm>process
-            <variablelist>the newly-created process.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, ,</para>
-      </sect2>
-
-      <sect2 id="PROCESS-INTERRUPT">
-        <para>PROCESS-INTERRUPT</para>
-        <informalfigure>process-interrupt</informalfigure>
-        <bridgehead renderas="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="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-interrupt
-	  process function &amp;rest args => result
-</programlisting>
-        <bridgehead renderas="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<literal>function</literal>.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>the result of applying <literal>function</literal>to <literal>args</literal> if <literal>proceess</literal>is the <literal>current-process</literal>, otherwiseNIL.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Arranges for <literal>process</literal> to apply <literal>function</literal> to <literal>args</literal> at
-some point in the near future (interrupting whatever <literal>process</literal>
-was doing.) If <literal>function</literal> returns normally, <literal>process</literal>
-resumes execution at the point at which it was interrupted.</para>
-        <para><literal>process</literal> must be in an enabled state in order 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.</para>
-        <para>Beginning with the version 1.1 prereleases of OpenMCL interrupts 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 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</literal> target
-(after all of that unwinding is complete.)</para>
-        <para>If an <literal>unwind-protect</literal> cleanup form actually does something that
-needs to be interruptible, it's necessary to use
-<literal>with-interrupts-enabled</literal>.  (This actually happens somewhere 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 the extent of
-the <literal>without-interrupts</literal>.</para>
-        <para>In versions prior to 1.1, interrupts could occur at arbitrary times
-during the process of unwinding the stack and executing intervening
-cleanup forms.</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>
-        <bridgehead renderas="sect3">See Also</bridgehead>
-        <para role="continues"></para>
-        <bridgehead renderas="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 signals between threads, via
-the C function <literal>#_pthread_signal</literal>.  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>
-      </sect2>
-
-      <sect2 id="iCURRENT-PROCESS-">
-        <para>*CURRENT-PROCESS*</para>
-        <informalfigure>*current-process*</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>*CURRENT-PROCESS* &mdash; Bound in each process, to that process
-itself.</para>
-        <para>Variable</para>
-        <bridgehead renderas="sect3">Value Type</bridgehead>
-        <para>A lisp process (thread).</para>
-        <bridgehead renderas="sect3">Initial Value</bridgehead>
-        <para>Bound separately in each process, to that process itself.</para>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues"></para>
-      </sect2>
-
-      <sect2 id="PROCESS-RESET">
-        <para>PROCESS-RESET</para>
-        <informalfigure>process-reset</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PROCESS-RESET &mdash; Causes a specified process to cleanly exit from
-any ongoing computation.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-reset
-	  process &amp;optional kill-option => result
-</programlisting>
-        <bridgehead renderas="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.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>undefined.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">,</para>
-      </sect2>
-
-      <sect2 id="PROCESS-KILL">
-        <para>PROCESS-KILL</para>
-        <informalfigure>process-kill</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PROCESS-KILL &mdash; Causes a specified process to cleanly exit from any
-ongoing computation, and then exit.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-kill process
-	  => result
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>process
-            <variablelist>a lisp process (thread).</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>undefined.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">,</para>
-      </sect2>
-
-      <sect2 id="PROCESS-ABORT">
-        <para>PROCESS-ABORT</para>
-        <informalfigure>process-abort</informalfigure>
-        <bridgehead renderas="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="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-abort process
-	  &amp;optional condition
-	  => NIL
-</programlisting>
-        <bridgehead renderas="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.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">,</para>
-      </sect2>
-
-      <sect2 id="iTICKS-PER-SECOND-">
-        <para>*TICKS-PER-SECOND*</para>
-        <informalfigure>*ticks-per-second*</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>*TICKS-PER-SECOND* &mdash; Bound to the clock resolution of the OS
-scheduler.</para>
-        <para>Variable</para>
-        <bridgehead renderas="sect3">Value Type</bridgehead>
-        <para>A positive integer.</para>
-        <bridgehead renderas="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="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="sect3">See Also</bridgehead>
-        <para role="continues"></para>
-      </sect2>
-
-      <sect2 id="PROCESS-WHOSTATE">
-        <para>PROCESS-WHOSTATE</para>
-        <informalfigure>process-whostate</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PROCESS-WHOSTATE &mdash; Returns a string which describes the status of
-a specified process.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-whostate process
-	  => 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="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="sect3">See Also</bridgehead>
-        <para role="continues">, ,</para>
-        <bridgehead renderas="sect3">Notes</bridgehead>
-        <para>This should arguably be SETFable, but doesn't seem to
-ever have been.</para>
-      </sect2>
-
-      <sect2 id="PROCESS-ALLOW-SCHEDULE">
-        <para>PROCESS-ALLOW-SCHEDULE</para>
-        <informalfigure>process-allow-schedule</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PROCESS-ALLOW-SCHEDULE &mdash; Used for cooperative multitasking; probably never
-necessary.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-allow-schedule
-</programlisting>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , ,</para>
-        <bridgehead renderas="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="PROCESS-WAIT">
-        <para>PROCESS-WAIT</para>
-        <informalfigure>process-wait</informalfigure>
-        <bridgehead renderas="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="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-wait
-	  whostate function &amp;rest args => result
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>whostate
-            <variablelist>a string, which will be the value ofwhile the process is waiting.</variablelist>
-          </indexterm><indexterm>function
-            <variablelist>a function, designated by itself or by a symbolwhich names it.</variablelist>
-          </indexterm><indexterm>args
-            <variablelist>a list of values, appropriate as arguments to<literal>function</literal>.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>NIL.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , , ,</para>
-      </sect2>
-
-      <sect2 id="PROCESS-WAIT-WITH-TIMEOUT">
-        <para>PROCESS-WAIT-WITH-TIMEOUT</para>
-        <informalfigure>process-wait-with-timeout</informalfigure>
-        <bridgehead renderas="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="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-wait-with-timeout
-	  whostate ticks function args => result
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>whostate
-            <variablelist>a string, which will be the value ofwhile the process is waiting.</variablelist>
-          </indexterm><indexterm>ticks
-            <variablelist>either a positive integer expressing a durationin "ticks" (see ),or NIL.</variablelist>
-          </indexterm><indexterm>function
-            <variablelist>a function, designated by itself or by a symbolwhich names it.</variablelist>
-          </indexterm><indexterm>args
-            <variablelist>a list of values, appropriate as arguments to<literal>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 it returned because the duration<literal>ticks</literal> has been exceeded.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id="WITHOUT-INTERRUPTS">
-        <para>WITHOUT-INTERRUPTS</para>
-        <informalfigure>without-interrupts</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>WITHOUT-INTERRUPTS &mdash; Evaluates its body in an environment in which
-process-interrupt requests are deferred.</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-without-interrupts
-	  &amp;body body => result
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>body
-            <variablelist>an implicit progn.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>the primary value returned by<literal>body</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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 interrupts 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> cleanup 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="sect3">See Also</bridgehead>
-        <para role="continues"></para>
-      </sect2>
-
-      <sect2 id="MAKE-LOCK">
-        <para>MAKE-LOCK</para>
-        <informalfigure>make-lock</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>MAKE-LOCK &mdash; Creates and returns a lock object, which can
-be used for synchronization between threads.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-make-lock &amp;optional
-	  name => lock
-</programlisting>
-        <bridgehead renderas="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.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id="WITH-LOCK-GRABBED">
-        <para>WITH-LOCK-GRABBED</para>
-        <informalfigure>with-lock-grabbed</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>WITH-LOCK-GRABBED &mdash; Waits until a given lock can be obtained, then
-evaluates its body with the lock held.</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-with-lock-grabbed
-	  (lock) &amp;body body
-</programlisting>
-        <bridgehead renderas="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</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id="GRAB-LOCK">
-        <para>GRAB-LOCK</para>
-        <informalfigure>grab-lock</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>GRAB-LOCK &mdash; Waits until a given lock can be obtained, then
-obtains it.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-grab-lock lock
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>lock
-            <variablelist>an object of type CCL:LOCK.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id="RELEASE-LOCK">
-        <para>RELEASE-LOCK</para>
-        <informalfigure>release-lock</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>RELEASE-LOCK &mdash; Relinquishes ownership of a given lock.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-release-lock lock
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>lock
-            <variablelist>an object of type CCL:LOCK.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id="TRY-LOCK">
-        <para>TRY-LOCK</para>
-        <informalfigure>try-lock</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>TRY-LOCK &mdash; Obtains the given lock, but only if it is not
-necessary to wait for it.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-try-lock lock => result
-</programlisting>
-        <bridgehead renderas="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,or NIL if it has not.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , , , ,</para>
-      </sect2>
-
-      <sect2 id="MAKE-READ-WRITE-LOCK">
-        <para>MAKE-READ-WRITE-LOCK</para>
-        <informalfigure>make-read-write-lock</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>MAKE-READ-WRITE-LOCK &mdash; Creates and returns a read-write lock, which can
-be used for synchronization between threads.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-make-read-write-lock
-	  => read-write-lock
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>read-write-lock
-            <variablelist>a newly-allocated object of typeCCL:READ-WRITE-LOCK.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , ,</para>
-        <bridgehead renderas="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="WITH-READ-LOCK">
-        <para>WITH-READ-LOCK</para>
-        <informalfigure>with-read-lock</informalfigure>
-        <bridgehead renderas="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="sect3">Synopsis</bridgehead>
-        <programlisting>
-with-read-lock
-	  (read-write-lock) &amp;body body => result
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>read-write-lock
-            <variablelist>an object of typeCCL:READ-WRITE-LOCK.</variablelist>
-          </indexterm><indexterm>body
-            <variablelist>an implicit progn.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>the primary value returned by<literal>body</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , ,</para>
-      </sect2>
-
-      <sect2 id="WITH-WRITE-LOCK">
-        <para>WITH-WRITE-LOCK</para>
-        <informalfigure>with-write-lock</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>WITH-WRITE-LOCK &mdash; Waits until the given lock is available for write
-access, then executes its body with the lock held.</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-with-write-lock
-	  (read-write-lock) &amp;body body
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>read-write-lock
-            <variablelist>an object of typeCCL:READ-WRITE-LOCK.</variablelist>
-          </indexterm><indexterm>body
-            <variablelist>an implicit progn.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>the primary value returned by<literal>body</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , ,</para>
-      </sect2>
-
-      <sect2 id="MAKE-SEMAPHORE">
-        <para>MAKE-SEMAPHORE</para>
-        <informalfigure>make-semaphore</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>MAKE-SEMAPHORE &mdash; Creates and returns a semaphore, which can be used
-for synchronization between threads.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-make-semaphore
-	  => semaphore
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>semaphore
-            <variablelist>a newly-allocated object of type CCL:SEMAPHORE.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , , ,</para>
-      </sect2>
-
-      <sect2 id="SIGNAL-SEMAPHORE">
-        <para>SIGNAL-SEMAPHORE</para>
-        <informalfigure>signal-semaphore</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SIGNAL-SEMAPHORE &mdash; Atomically increments the count of a given
-semaphore.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-signal-semaphore
-	  semaphore => result
-</programlisting>
-        <bridgehead renderas="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="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , , ,</para>
-        <bridgehead renderas="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="WAIT-ON-SEMAPHORE">
-        <para>WAIT-ON-SEMAPHORE</para>
-        <informalfigure>wait-on-semaphore</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>WAIT-ON-SEMAPHORE &mdash; Waits until the given semaphore has a positive
-count which can be atomically decremented.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-wait-on-semaphore
-	  semaphore => result
-</programlisting>
-        <bridgehead renderas="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.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , , ,</para>
-        <bridgehead renderas="sect3">Notes</bridgehead>
-      </sect2>
-
-      <sect2 id="TIMED-WAIT-ON-SEMAPHORE">
-        <para>TIMED-WAIT-ON-SEMAPHORE</para>
-        <informalfigure>timed-wait-on-semaphore</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>TIMED-WAIT-ON-SEMAPHORE &mdash; Waits until the given semaphore has a postive
-count which can be atomically decremented, or until a timeout
-expires.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-timed-wait-on-semaphore
-	  semaphore timeout => result
-</programlisting>
-        <bridgehead renderas="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-negative 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>returned because it was able to decrement the count of<literal>semaphore</literal>; NIL if it returned becausethe duration <literal>timeout</literal> has beenexceeded.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , , , ,</para>
-      </sect2>
-
-      <sect2 id="PROCESS-INPUT-WAIT">
-        <para>PROCESS-INPUT-WAIT</para>
-        <informalfigure>process-input-wait</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PROCESS-INPUT-WAIT &mdash; Waits until input is available on a given
-file-descriptor.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-input-wait
-	  fd &amp;optional timeout
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>fd
-            <variablelist>a file descriptor, which is a non-negative integerused 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="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , ,</para>
-        <bridgehead renderas="sect3">Notes</bridgehead>
-        <para><literal>process-input-wait</literal> has a timeout parameter,
-and
- does not.  This
-inconsistency should probably be corrected.</para>
-      </sect2>
-
-      <sect2 id="PROCESS-OUTPUT-WAIT">
-        <para>PROCESS-OUTPUT-WAIT</para>
-        <informalfigure>process-output-wait</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PROCESS-OUTPUT-WAIT &mdash; Waits until output is possible on a given file
-descriptor.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-process-output-wait fd
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>fd
-            <variablelist>a file descriptor, which is a non-negative integerused by the OS to refer to an open file, socket, or similarI/O connection.  See CCL::STREAM-DEVICE.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, , , ,</para>
-        <bridgehead renderas="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="WITH-TERMINAL-INPUT">
-        <para>WITH-TERMINAL-INPUT</para>
-        <informalfigure>with-terminal-input</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>WITH-TERMINAL-INPUT &mdash; Executes its body in an environment with exclusive
-read access to the terminal.</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-with-terminal-input
-	  &amp;body body => result
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>body
-            <variablelist>an implicit progn.</variablelist>
-          </indexterm><indexterm>result
-            <variablelist>the primary value returned by<literal>body</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, :Y, , , , ,</para>
-      </sect2>
-
-      <sect2 id="iREQUEST-TERMINAL-INPUT-VIA-BREAK-">
-        <para>*REQUEST-TERMINAL-INPUT-VIA-BREAK*</para>
-        <informalfigure>request-terminal-input-via-break</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>*REQUEST-TERMINAL-INPUT-VIA-BREAK* &mdash; Controls how attempts to obtain ownership of
-terminal input are made.</para>
-        <para>Variable</para>
-        <bridgehead renderas="sect3">Value Type</bridgehead>
-        <para>A boolean.</para>
-        <bridgehead renderas="sect3">Initial Value</bridgehead>
-        <para>NIL.</para>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="continues">, :Y, , , , ,</para>
-      </sect2>
-
-      <sect2 id="iY">
-        <para>:Y</para>
-        <informalfigure>:y</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>:Y &mdash; Yields control of terminal input to a specified
-lisp process (thread).</para>
-        <para>Toplevel Command</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-(:y p)
-</programlisting>
-        <bridgehead renderas="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 string which is <literal>equal</literal> toits <literal>process-name</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">See Also</bridgehead>
-        <para role="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="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="f_process-suspend"/> call
+	  is one which has not yet been reversed by a call to
+	  <xref linkend="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="f_process-preset"/>, and has been
+	  enabled as by <xref linkend="f_process-enable"/>.  Newly-created
+	  processes have a <function>process-suspend-count</function> of
+	  0.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 
+	  <simplelist type="inline">
+	    <member><xref linkend="f_process-suspend"/></member>
+	    <member><xref linkend="f_process-resume"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_process-preset">
+	<indexterm zone="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
+	  => 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="f_process-enable"/>.
+	  </para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 
+	  <simplelist type="inline">
+	    <member><xref linkend="f_make-process"/></member>
+	    <member><xref linkend="f_process-enable"/></member>
+	    <member><xref linkend="f_process-run-function"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_process-enable">
+	<indexterm zone="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="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="inline">
+	    <member><xref linkend="f_make-process"/></member>
+	    <member><xref linkend="f_process-preset"/></member>
+	    <member><xref linkend="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="f_process-run-function">
+	<indexterm zone="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 => 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="f_make-process"/>,
+	  presets it via <xref linkend="f_process-preset"/>, and
+	  enables it via <xref linkend="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="inline">
+	    <member><xref linkend="f_make-process"/></member>
+	    <member><xref linkend="f_process-preset"/></member>
+	    <member><xref linkend="f_process-enable"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_process-interrupt">
+	<indexterm zone="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 => 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="inline">
+	    <member><xref linkend="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="v_current-process">
+	<indexterm zone="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="inline">
+	    <member><xref linkend="f_all-processes"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_process-reset">
+	<indexterm zone="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 => 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="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="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="v_current-process"/> involves the
+	  use of <xref linkend="f_process-interrupt"/>.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 
+	  <simplelist type="inline">
+	    <member><xref linkend="f_process-kill"/></member>
+	    <member><xref linkend="f_process-abort"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_process-kill">
+	<indexterm zone="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
+	  => 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="inline">
+	    <member><xref linkend="f_process-reset"/></member>
+	    <member><xref linkend="f_process-abort"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_process-abort">
+	<indexterm zone="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
+	  => 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="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="inline">
+	    <member><xref linkend="f_process-reset"/></member>
+	    <member><xref linkend="f_process-kill"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="v_ticks-per-second">
+	<indexterm zone="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="inline">
+	    <member><xref linkend="f_process-wait-with-timeout"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_process-whostate">
+	<indexterm zone="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
+	  => 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="f_process-wait"/> or
+	  <xref linkend="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="inline">
+	    <member><xref linkend="f_process-wait"/></member>
+	    <member><xref linkend="f_process-wait-with-timeout"/></member>
+	    <member><xref linkend="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="f_process-allow-schedule">
+	<indexterm zone="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="inline">
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="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="f_process-wait">
+	<indexterm zone="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 => 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="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="f_process-allow-schedule"/>.</para>
+	  
+	  <para>
+	  As with <xref linkend="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="inline">
+	    <member><xref linkend="f_process-whostate"/></member>
+	    <member><xref linkend="f_process-wait-with-timeout"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_process-wait-with-timeout">
+	<indexterm zone="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 => 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="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="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="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="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="f_process-allow-schedule"/> and
+	  <xref linkend="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="inline">
+	    <member><xref linkend="v_ticks-per-second"/></member>
+	    <member><xref linkend="f_process-whostate"/></member>
+	    <member><xref linkend="f_process-wait"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="m_without-interrupts">
+	<indexterm zone="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 => 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="f_process-interrupt"/>
+	  requests are
+	  deferred. As noted in the description of
+	  <xref linkend="f_process-interrupt"/>, this has nothing to do
+	  with the
+	  scheduling of other threads; it may be necessary to inhibit
+	  <xref linkend="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="inline">
+	    <member><xref linkend="f_process-interrupt"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_make-lock">
+	<indexterm zone="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 => 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="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="inline">
+	    <member><xref linkend="m_with-lock-grabbed"/></member>
+	    <member><xref linkend="f_grab-lock"/></member>
+	    <member><xref linkend="f_release-lock"/></member>
+	    <member><xref linkend="f_try-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="m_with-lock-grabbed">
+	<indexterm zone="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="inline">
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_grab-lock"/></member>
+	    <member><xref linkend="f_release-lock"/></member>
+	    <member><xref linkend="f_try-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_grab-lock">
+	<indexterm zone="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="m_with-lock-grabbed"/>
+	  <emphasis>could</emphasis> be defined in
+	  terms of <function>grab-lock</function> and
+	  <xref linkend="f_release-lock"/>, but it is actually
+	  implemented at a slightly lower level.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 
+	  <simplelist type="inline">
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="m_with-lock-grabbed"/></member>
+	    <member><xref linkend="f_release-lock"/></member>
+	    <member><xref linkend="f_try-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_release-lock">
+	<indexterm zone="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="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="f_grab-lock"/> has, <varname>lock</varname>
+	  becomes free.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 
+	  <simplelist type="inline">
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="m_with-lock-grabbed"/></member>
+	    <member><xref linkend="f_grab-lock"/></member>
+	    <member><xref linkend="f_try-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_try-lock">
+	<indexterm zone="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 => 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="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="inline">
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="m_with-lock-grabbed"/></member>
+	    <member><xref linkend="f_grab-lock"/></member>
+	    <member><xref linkend="f_release-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_make-read-write-lock">
+	<indexterm zone="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>
+	  => 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="inline">
+	    <member><xref linkend="m_with-read-lock"/></member>
+	    <member><xref linkend="m_with-write-lock"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="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="m_with-read-lock">
+	<indexterm zone="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 => 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="v_current-process"/> is a
+	  reader of it, then executes <varname>body</varname>.
+	  </para>
+
+	  <para>After executing <varname>body</varname>, if
+	  <xref linkend="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="inline">
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="m_with-write-lock"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="m_with-write-lock">
+	<indexterm zone="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="v_current-process"/>,
+	  then ensures that <xref linkend="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="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="inline">
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="m_with-read-lock"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_make-semaphore">
+	<indexterm zone="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>
+	  => 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="inline">
+	    <member><xref linkend="f_signal-semaphore"/></member>
+	    <member><xref linkend="f_wait-on-semaphore"/></member>
+	    <member><xref linkend="f_timed-wait-on-semaphore"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_signal-semaphore">
+	<indexterm zone="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 => 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="inline">
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_wait-on-semaphore"/></member>
+	    <member><xref linkend="f_timed-wait-on-semaphore"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="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="f_wait-on-semaphore">
+	<indexterm zone="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 => 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="inline">
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_signal-semaphore"/></member>
+	    <member><xref linkend="f_timed-wait-on-semaphore"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="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="f_timed-wait-on-semaphore">
+	<indexterm zone="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 => 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="inline">
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_wait-on-semaphore"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_process-input-wait">
+	<indexterm zone="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="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="inline">
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>
+	  <function>process-input-wait</function> has a timeout parameter,
+	  and
+	  <xref linkend="f_process-output-wait"/> does not.  This
+	  inconsistency should probably be corrected.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_process-output-wait">
+	<indexterm zone="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="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="inline">
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	  </simplelist>
+	</refsect1>
+
+	<refsect1>
+	  <title>Notes</title>
+
+	  <para>
+	  <xref linkend="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="m_with-terminal-input">
+	<indexterm zone="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 => 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="inline">
+	    <member><xref
+	              linkend="v_request-terminal-input-via-break"/></member>
+	    <member><xref linkend="cmd_y"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="v_request-terminal-input-via-break">
+	<indexterm zone="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="inline">
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	    <member><xref linkend="cmd_y"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="cmd_y">
+	<indexterm zone="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="m_with-terminal-input"/> to request access to the
+	  terminal input stream.</para>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+	 
+	  <simplelist type="inline">
+	    <member><xref linkend="m_with-terminal-input"/></member>
+	    <member><xref
+	              linkend="v_request-terminal-input-via-break"/></member>
+	    <member><xref linkend="f_make-lock"/></member>
+	    <member><xref linkend="f_make-read-write-lock"/></member>
+	    <member><xref linkend="f_make-semaphore"/></member>
+	    <member><xref linkend="f_process-input-wait"/></member>
+	    <member><xref linkend="f_process-output-wait"/></member>
+	  </simplelist>
+	</refsect1>
+      </refentry>
+
     </sect1>
   </chapter>
@@ -3133,5 +4388,7 @@
 
     <sect1 id="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
@@ -3144,627 +4401,1370 @@
       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 connection.tcp-stream is a subclass of stream, and you can read and write to itusing all the usual stream functions. Created by (make-socket:addess-family :internet :type :stream :connect :active ...) or by(accept-connection ...).</variablelist>
-        </indexterm><indexterm>file-socket-stream
-          <variablelist>A buffered bi-directional stream over a "UNIX domain"connection. file-socket-stream is a subclass of stream, and you canread and write to it using all the usual stream functions. Createdby (make-socket :address-family :file :type :stream :connect :active...) or by (accept-connection ...),</variablelist>
-        </indexterm><indexterm>listener-socket
-          <variablelist>A passive socket used to listen for incoming TCP/IPconnections on a particular port. A listener-socket is not a stream.It doesn't support I/O. It can only be used to create newtcp-streams by accept-connection. Created by (make-socket :type:stream :connect :passive ...)</variablelist>
-        </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-family :file :type :stream :connect:passive ...)</variablelist>
-        </indexterm><indexterm>udp-socket
-          <variablelist>A socket representing a packet-based UDP/IP connection. 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. Created by (make-socket :type :datagram ...)</variablelist>
-        </indexterm>
-      </term>
+      created by <xref linkend="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="Sockets-Dictionary">
       <title>Sockets Dictionary</title>
-
-      <sect2 id="MAKE-SOCKET">
-        <para>MAKE-SOCKET</para>
-        <informalfigure>make-socket</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>MAKE-SOCKET &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-make-socket
-	  &amp;key address-family type connect eol format
+      <refentry id="f_make-socket">
+	<indexterm zone="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="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>address-family
-            <variablelist>The address/protocol family of this socket. Currentlyonly :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 aconnection-oriented socket, or :datagram to request aconnectionless socket. The default is :stream.</variablelist>
-          </indexterm><indexterm>connect
-            <variablelist>This argument is only relevant to sockets of type:stream. One of :active (the default) to request a :passiveto request a file or TCP listener socket.</variablelist>
-          </indexterm><indexterm>eol
-            <variablelist>This argument is currently ignored (it is accepted forcompatibility with Franz Allegro).</variablelist>
-          </indexterm><indexterm>format
-            <variablelist>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. theysupport both character and byte I/O). For :datagram sockets,the format determines the type of buffer created byreceive-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 listener 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 subsequent calls to forsubsequent calls to send-to or receive-from.</variablelist>
-          </indexterm><indexterm>remote-filename
-            <variablelist>Required for file-socket streams, it specifies thename of a file in the local filesystem (e.g., NOT mountedvia NFS, AFP, SMB, ...) which names and controls access to aUNIX-domain socket.</variablelist>
-          </indexterm><indexterm>local-host
-            <variablelist>Allows you to specify a local host address for alistener or UDP socket, for the rare case where you want torestrict connections to those coming to a specific localaddress for security reasons.</variablelist>
-          </indexterm><indexterm>local-port
-            <variablelist>Specify a local port for a socket. Most useful forlistener 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 the 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 writable by thecaller. The file used to name the socket will be deletedwhen the file-listener-socket is closed.</variablelist>
-          </indexterm><indexterm>keepalive
-            <variablelist>If true, enables the periodic transmission of"keepalive" messages.</variablelist>
-          </indexterm><indexterm>reuse-address
-            <variablelist>If true, allows the reuse of local ports in listenersockets, overriding some TCP/IP protocol specifications. Youwill need this if you are debugging a server..</variablelist>
-          </indexterm><indexterm>nodelay
-            <variablelist>If true, disables Nagle's algorithm, which triesto minimize TCP packet fragmentation by introducingtransmission delays in the absence of replies. Try settingthis if you are using a protocol which involves sending asteady stream of data with no replies and are seeingsignificant degradations in throughput.</variablelist>
-          </indexterm><indexterm>broadcast
-            <variablelist>If true, requests permission to broadcast datagrams ona UDP socket.</variablelist>
-          </indexterm><indexterm>linger
-            <variablelist>If specified and non-nil, should be the number ofseconds the OS is allowed to wait for data to be pushedthrough when a close is done. Only relevant for TCP sockets.</variablelist>
-          </indexterm><indexterm>backlog
-            <variablelist>For a listener socket, specifies the number ofconnections which can be pending but not accepted. Thedefault is 5, which is also the maximum on some operatingsystems.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Creates and returns a new socket</para>
-      </sect2>
-
-      <sect2 id="ACCEPT-CONNECTION">
-        <para>ACCEPT-CONNECTION</para>
-        <informalfigure>accept-connection</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>ACCEPT-CONNECTION &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-accept-connection
-	  (socket listener-socket) &amp;key wait
-</programlisting>
-        <bridgehead renderas="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 connectionswaiting to be accepted, waits until one arrives. If false,returns NIL immediately.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="DOTTED-TO-IPADDR">
-        <para>DOTTED-TO-IPADDR</para>
-        <informalfigure>dotted-to-ipaddr</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>DOTTED-TO-IPADDR &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-dotted-to-ipaddr
-	  dotted &amp;key errorp
-</programlisting>
-        <bridgehead renderas="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 dottedis invalid. If false, NIL is returned.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Converts a dotted-string representation of a host address to
-a 32-bit unsigned IP address.</para>
-      </sect2>
-
-      <sect2 id="IPADDR-TO-DOTTED">
-        <para>IPADDR-TO-DOTTED</para>
-        <informalfigure>ipaddr-to-dotted</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>IPADDR-TO-DOTTED &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-ipaddr-to-dotted
-	  ipaddr &amp;key values
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>ipaddr
-            <variablelist>A 32-bit integer representing an internet host address</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="sect3">Description</bridgehead>
-        <para>Converts a 32-bit unsigned IP address into octets.</para>
-      </sect2>
-
-      <sect2 id="IPADDR-TO-HOSTNAME">
-        <para>IPADDR-TO-HOSTNAME</para>
-        <informalfigure>ipaddr-to-hostname</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>IPADDR-TO-HOSTNAME &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-ipaddr-to-hostname
-	  ipaddr &amp;key ignore-cache
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>ipaddr
-            <variablelist>a 32-bit integer representing an internet host address</variablelist>
-          </indexterm><indexterm>ignore-cache
-            <variablelist>This argument is ignored (it is accepted forcompatibility with Franz Allegro)</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Converts a 32-bit unsigned IP address into a host name
-string</para>
-      </sect2>
-
-      <sect2 id="LOOKUP-HOSTNAME">
-        <para>LOOKUP-HOSTNAME</para>
-        <informalfigure>lookup-hostname</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>LOOKUP-HOSTNAME &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-lookup-hostname
-	  host
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>host
-            <variablelist>Specifies the host. It can be either a host namestring 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="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="LOOKUP-PORT">
-        <para>LOOKUP-PORT</para>
-        <informalfigure>lookup-port</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>LOOKUP-PORT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-lookup-port
-	  port protocol
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>port
-            <variablelist>Specifies the port. It can be either a string, such as"http" or a symbol, such as :http, or an unsignedport number. Note that a string is case-sensitive. A symbolis lowercased before lookup.</variablelist>
-          </indexterm><indexterm>protocol
-            <variablelist>Must be one of "tcp" or "udp".</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Finds the port number for the specified port and protocol</para>
-      </sect2>
-
-      <sect2 id="RECEIVE-FROM">
-        <para>RECEIVE-FROM</para>
-        <informalfigure>receive-from</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>RECEIVE-FROM &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-receive-from
-	  (socket udp-socket) size &amp;key buffer
-	  extract offset
-</programlisting>
-        <bridgehead renderas="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 islarger 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 correspondingonly to the data read in is extracted and returned as thefirst value. If false (the default) the original buffer isreturned even if it is only partially filled.</variablelist>
-          </indexterm><indexterm>offset
-            <variablelist>Specifies the start offset into the buffer at whichdata is to be stored. The default is 0.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="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 the data</variablelist>
-          <variablelist>The port number of the sender of the data</variablelist>
-        </varlistentry>
-      </sect2>
-
-      <sect2 id="SEND-TO">
-        <para>SEND-TO</para>
-        <informalfigure>send-to</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SEND-TO &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-send-to
-	  (socket udp-socket) buffer size &amp;key remote-host
-	  remote-port offset
-</programlisting>
-        <bridgehead renderas="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 beeither 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 formatacceptable 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 formatacceptable 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 starts</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Send a UDP packet over a socket.</para>
-      </sect2>
-
-      <sect2 id="SHUTDOWN">
-        <para>SHUTDOWN</para>
-        <informalfigure>shutdown</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SHUTDOWN &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-shutdown
-	  socket &amp;key direction
-</programlisting>
-        <bridgehead renderas="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 :output todisallow further output.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="SOCKET-OS-FD">
-        <para>SOCKET-OS-FD</para>
-        <informalfigure>socket-os-fd</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SOCKET-OS-FD &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-os-fd
-	  socket
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="REMOTE-HOST">
-        <para>REMOTE-HOST</para>
-        <informalfigure>remote-host</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>REMOTE-HOST &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-remote-host
-	  socket
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="REMOTE-PORT">
-        <para>REMOTE-PORT</para>
-        <informalfigure>remote-port</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>REMOTE-PORT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-remote-port
-	  socket
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns the remote port number, or NIL if the socket is not
-connected.</para>
-      </sect2>
-
-      <sect2 id="LOCAL-HOST">
-        <para>LOCAL-HOST</para>
-        <informalfigure>local-host</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>LOCAL-HOST &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-local-host
-	  socket
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns 32-bit unsigned IP address of the local host.</para>
-      </sect2>
-
-      <sect2 id="LOCAL-PORT">
-        <para>LOCAL-PORT</para>
-        <informalfigure>local-port</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>LOCAL-PORT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-local-port
-	  socket
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns the local port number</para>
-      </sect2>
-
-      <sect2 id="SOCKET-ADDRESS-FAMILY">
-        <para>SOCKET-ADDRESS-FAMILY</para>
-        <informalfigure>socket-address-family</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SOCKET-ADDRESS-FAMILY &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-address-family
-	  socket
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns :internet or :file, as appropriate.</para>
-      </sect2>
-
-      <sect2 id="SOCKET-CONNECT">
-        <para>SOCKET-CONNECT</para>
-        <informalfigure>socket-connect</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SOCKET-CONNECT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-connect
-	  socket
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns :active for tcp-stream, :passive for
-listener-socket, and NIL for udp-socket</para>
-      </sect2>
-
-      <sect2 id="SOCKET-FORMAT">
-        <para>SOCKET-FORMAT</para>
-        <informalfigure>socket-format</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SOCKET-FORMAT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-format
-	  socket
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns the socket format as specified by the :format
-argument to make-socket.</para>
-      </sect2>
-
-      <sect2 id="SOCKET-TYPE">
-        <para>SOCKET-TYPE</para>
-        <informalfigure>socket-type</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SOCKET-TYPE &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-type
-	  socket
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket
-            <variablelist>The socket</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>returns :stream for tcp-stream and listener-socket, and
-:datagram for udp-socket.</para>
-      </sect2>
-
-      <sect2 id="SOCKET-ERROR">
-        <para>SOCKET-ERROR</para>
-        <informalfigure>socket-error</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SOCKET-ERROR &mdash;</para>
-        <para>Class</para>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>The class of OS errors signaled by socket functions</para>
-        <bridgehead renderas="sect3">Superclasses</bridgehead>
-        <para>simple-error</para>
-      </sect2>
-
-      <sect2 id="SOCKET-ERROR-CODE">
-        <para>SOCKET-ERROR-CODE</para>
-        <informalfigure>socket-error-code</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SOCKET-ERROR-CODE &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-error-code
-	  socket-error
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket-error
-            <variablelist>the condition</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>The OS error code of the error</para>
-      </sect2>
-
-      <sect2 id="SOCKET-ERROR-IDENTIFIER">
-        <para>SOCKET-ERROR-IDENTIFIER</para>
-        <informalfigure>socket-error-identifier</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SOCKET-ERROR-IDENTIFIER &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-error-identifier
-	  socket-error
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket-error
-            <variablelist>the condition</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="SOCKET-ERROR-SITUATION">
-        <para>SOCKET-ERROR-SITUATION</para>
-        <informalfigure>socket-error-situation</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SOCKET-ERROR-SITUATION &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-socket-error-situation
-	  socket-error
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>socket-error
-            <variablelist>the condition</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="CLOSE">
-        <para>CLOSE</para>
-        <informalfigure>close</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CLOSE &mdash;</para>
-        <para>Method</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-close
-	  (socket socket) &amp;key abort
-</programlisting>
-        <bridgehead renderas="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 anorderly fashion, finishing up any buffered pending I/O,before closing the connection. 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="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="WITH-OPEN-SOCKET">
-        <para>WITH-OPEN-SOCKET</para>
-        <informalfigure>with-open-socket</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>WITH-OPEN-SOCKET &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-with-open-socket
-	  (var . make-socket-args) &amp;body body
-</programlisting>
-        <bridgehead renderas="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</variablelist>
-          </indexterm><indexterm>body
-            <variablelist>body to execute</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="f_accept-connection">
+	<indexterm zone="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="f_dotted-to-ipaddr">
+	<indexterm zone="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="f_ipaddr-to-dotted">
+	<indexterm zone="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="f_ipaddr-to-hostname">
+	<indexterm zone="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="f_lookup-hostname">
+	<indexterm zone="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="f_lookup-port">
+	<indexterm zone="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="f_receive-from">
+	<indexterm zone="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="restarts" inheritnum="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</para>
+	    </listitem>
+
+	    <listitem>
+	      <para>The port number of the sender of the data</para>
+	    </listitem>
+	  </orderedlist>
+	</refsect1>
+      </refentry>
+
+      <refentry id="f_send-to">
+	<indexterm zone="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="f_shutdown">
+	<indexterm zone="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="f_socket-os-fd">
+	<indexterm zone="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="f_remote-host">
+	<indexterm zone="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="f_remote-port">
+	<indexterm zone="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="f_local-host">
+	<indexterm zone="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="f_local-port">
+	<indexterm zone="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="f_socket-address-family">
+	<indexterm zone="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="f_socket-connect">
+	<indexterm zone="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="f_socket-format">
+	<indexterm zone="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="f_socket-type">
+	<indexterm zone="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="c_socket-error">
+	<indexterm zone="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="f_socket-error-code">
+	<indexterm zone="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="f_socket-error-identifier">
+	<indexterm zone="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="f_socket-error-situation">
+	<indexterm zone="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="o_close">
+	<indexterm zone="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="m_with-open-socket">
+	<indexterm zone="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>
@@ -3805,5 +5805,5 @@
 
     <sect1 id="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
@@ -3821,197 +5821,421 @@
     <sect1 id="External-Program-Dictionary">
       <title>External-Program Dictionary</title>
-
-      <sect2 id="RUN-PROGRAM">
-        <para>RUN-PROGRAM</para>
-        <informalfigure>run-program</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>RUN-PROGRAM &mdash; Invokes an external program as an OS subprocess
-of lisp.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-run-program
-	    program args &amp;key (wait t) pty input
+	<refentry id="f_run-program">
+	  <indexterm zone="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="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 doesn'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.</variablelist>
-          </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-PROCESS.May be any of the following:
-              <listitem mark="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 theEXTERNAL-PROCESS should receive its input from the namedexisting file.</variablelist>
-                <variablelist>:STREAM Creates a Lisp stream opened for characteroutput. Any data written to this stream (accessible asthe EXTERNAL-PROCESS-INPUT-STREAM of theEXTERNAL-PROCESS object) appears as input to theexternal process.</variablelist>
-                <variablelist>A stream. Specifies that the lisp stream shouldprovide input to the EXTERNAL-PROCESS.</variablelist>
-              
-              </listitem>
-</variablelist>
-          </indexterm><indexterm>if-input-does-not-exist
-            <variablelist>If the input argument specifies the name of anexisting 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 externalprocess 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 opened.</variablelist>
-          </indexterm><indexterm>error
-            <variablelist>Specifies where error output from the external processshould be sent. In addition to the values allowed foroutput, the keyword :OUTPUT can be used to indicate thaterror output should be sent where standard 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 (theEXTERNAL-PROCESS structure.) This function is calledwhenever OpenMCL detects a change in the staus of theEXTERNAL-PROCESS.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="SIGNAL-EXTERNAL-PROCESS">
-        <para>SIGNAL-EXTERNAL-PROCESS</para>
-        <informalfigure>signal-external-process</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SIGNAL-EXTERNAL-PROCESS &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-signal-external-process
-	    proc signal-number
-</programlisting>
-        <bridgehead renderas="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="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="EXTERNAL-PROCESS-ID">
-        <para>EXTERNAL-PROCESS-ID</para>
-        <informalfigure>external-process-id</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>EXTERNAL-PROCESS-ID &mdash; Returns the "process ID" of an OS subprocess,
-a positive integer which identifies it.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-external-process-id
-	    proc
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>proc
-            <variablelist>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="EXTERNAL-PROCESS-INPUT-STREAM">
-        <para>EXTERNAL-PROCESS-INPUT-STREAM</para>
-        <informalfigure>external-process-input-stream</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>EXTERNAL-PROCESS-INPUT-STREAM &mdash; Returns the lisp stream which is used to write
-input to a given OS subprocess, if it has one.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-external-process-input-stream
-	    proc
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>proc
-            <variablelist>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns the stream created when the input argument to
-run-program is specified as :STREAM.</para>
-      </sect2>
-
-      <sect2 id="EXTERNAL-PROCESS-OUTPUT-STREAM">
-        <para>EXTERNAL-PROCESS-OUTPUT-STREAM</para>
-        <informalfigure>external-process-output-stream</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>EXTERNAL-PROCESS-OUTPUT-STREAM &mdash; Returns the lisp stream which is used to read
-output from an OS subprocess, if there is one.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-external-process-output-stream
-	    proc
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>proc
-            <variablelist>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns the stream created when the output argument to
-run-program is specified as :STREAM.</para>
-      </sect2>
-
-      <sect2 id="EXTERNAL-PROCESS-ERROR-STREAM">
-        <para>EXTERNAL-PROCESS-ERROR-STREAM</para>
-        <informalfigure>external-process-error-stream</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>EXTERNAL-PROCESS-ERROR-STREAM &mdash; Returns the stream which is used to read
-"error" output from a given OS subprocess, if it has
-one.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-external-process-error-stream
-	    proc
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>proc
-            <variablelist>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns the stream created when the error argument to
-run-program is specified as :STREAM.</para>
-      </sect2>
-
-      <sect2 id="EXTERNAL-PROCESS-STATUS">
-        <para>EXTERNAL-PROCESS-STATUS</para>
-        <informalfigure>external-process-status</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>EXTERNAL-PROCESS-STATUS &mdash; Returns information about whether 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="sect3">Synopsis</bridgehead>
-        <programlisting>
-external-process-status
-	    proc
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>proc
-            <variablelist>An EXTERNAL-PROCESS, as returned by RUN-PROGRAM.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="f_signal-external-process">
+	  <indexterm zone="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="f_external-process-id">
+	  <indexterm zone="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="f_external-process-input-stream">
+	  <indexterm zone="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="f_external-process-output-stream">
+	  <indexterm zone="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="f_external-process-error-stream">
+	  <indexterm zone="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="f_external-process-status">
+	  <indexterm zone="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>
@@ -4038,368 +6262,145 @@
       <para>Here's a list of some classes which you might wish for
       your new stream class to inherit from:</para>
-      <colspec>
-        <thead cols="1">
-          <tbody colwidth="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, 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>
+ 
+      <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="1">
-          <tbody colwidth="100*"></tbody>
-          <row>
-            <abstract>
-              <entry>stream-direction stream =></entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-device stream direction =></entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-length stream <literal>&amp;optional</literal>new =></entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-position stream <literal>&amp;optional</literal>new =></entry>
-            
-            </abstract>
-            <abstract>
-              <entry>streamp stream => boolean</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-write-char output-stream char =></entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-write-entire-string output-stream string =></entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-read-char input-stream =></entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-unread-char input-stream char =></entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-force-output output-stream => nil</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-maybe-force-output output-stream => nil</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-finish-output output-stream => nil</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-clear-output output-stream => nil</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>close stream <literal>&amp;key</literal>abort => boolean</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-fresh-line stream => t</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-line-length stream => length</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>interactive-stream-p stream => boolean</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-clear-input input-stream => nil</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-listen input-stream => boolean</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-filename stream => string</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>ccl::select-stream-class instance in-p out-p char-p =>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 =></member>
+	<member>stream-device stream direction =></member>
+	<member>stream-length stream &optional; new =></member>
+	<member>stream-position stream &optional; new =></member>
+	<member>streamp stream => boolean</member>
+	<member>stream-write-char output-stream char =></member>
+	<member>stream-write-entire-string output-stream string =></member>
+	<member>stream-read-char input-stream =></member>
+	<member>stream-unread-char input-stream char =></member>
+	<member>stream-force-output output-stream => nil</member>
+	<member>stream-maybe-force-output output-stream => nil</member>
+	<member>stream-finish-output output-stream => nil</member>
+	<member>stream-clear-output output-stream => nil</member>
+	<member>close stream &key; abort => boolean</member>
+	<member>stream-fresh-line stream => t</member>
+	<member>stream-line-length stream => length</member>
+	<member>interactive-stream-p stream => boolean</member>
+	<member>stream-clear-input input-stream => nil</member>
+	<member>stream-listen input-stream => boolean</member>
+	<member>stream-filename stream => string</member>
+	<member>ccl::select-stream-class instance in-p out-p char-p =>
+	        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="1">
-          <tbody colwidth="100*"></tbody>
-          <row>
-            <abstract>
-              <entry>open-stream-p stream => generalized-boolean</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>input-stream-p stream => generalized-boolean</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>output-stream-p stream => generalized-boolean</entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-element-type stream =></entry>
-            
-            </abstract>
-            <abstract>
-              <entry>stream-error-stream =></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="1">
-          <tbody colwidth="100*"></tbody>
-          <row>
-            <abstract>
-              <entry>stream-external-format</entry>
-            
-            </abstract>
-          </row>
-        </thead>
-      </colspec>
+      <simplelist>
+	<member>open-stream-p stream => generalized-boolean</member>
+	<member>input-stream-p stream => generalized-boolean</member>
+	<member>output-stream-p stream => generalized-boolean</member>
+	<member>stream-element-type stream =></member>
+	<member>stream-error-stream =></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>
 
@@ -4476,207 +6477,465 @@
     <sect1 id="Gray-Streams-Dictionary">
       <title>Gray Streams Dictionary</title>
-
-      <sect2 id="CCL-STREAM-READ-LIST">
-        <para>CCL:STREAM-READ-LIST</para>
-        <informalfigure>stream-read-list</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL:STREAM-READ-LIST &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-read-list
-	  stream list count
-</programlisting>
-        <bridgehead renderas="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.</variablelist>
-          </indexterm><indexterm>count
-            <variablelist>a non-negative integer. When a STREAM-READ-LIST methodis called by READ-SEQUENCE, this argument is guaranteed notto be greater than the length of the list.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="CCL-STREAM-WRITE-LIST">
-        <para>CCL:STREAM-WRITE-LIST</para>
-        <informalfigure>stream-write-list</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL:STREAM-WRITE-LIST &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-write-list
-	  stream list count
-</programlisting>
-        <bridgehead renderas="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 called byWRITE-SEQUENCE, this argument is guaranteed to be a properlist.</variablelist>
-          </indexterm><indexterm>count
-            <variablelist>a non-negative integer. When a STREAM-WRITE-LISTmethod is called by WRITE-SEQUENCE, this argument isguaranteed not to be greater than the length of the list.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="CCL-STREAM-READ-VECTOR">
-        <para>CCL:STREAM-READ-VECTOR</para>
-        <informalfigure>stream-read-vector</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL:STREAM-READ-VECTOR &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-read-vector
-	  stream vector start end
-</programlisting>
-        <bridgehead renderas="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 calledby READ-SEQUENCE, this argument is guaranteed to be a simpleone-dimensional array.</variablelist>
-          </indexterm><indexterm>start
-            <variablelist>a non-negative integer. When a STREAM-READ-VECTORmethod is called by READ-SEQUENCE, this argument isguaranteed to be no greater than end and not greater thanthe length of vector.</variablelist>
-          </indexterm><indexterm>end
-            <variablelist>a non-negative integer. When a STREAM-READ-VECTORmethod is called by READ-SEQUENCE, this argument isguaranteed to be no less than end and not greater than thelength of vector.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="CCL-STREAM-WRITE-VECTOR">
-        <para>CCL:STREAM-WRITE-VECTOR</para>
-        <informalfigure>stream-write-vector</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL:STREAM-WRITE-VECTOR &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-write-vector
-	  stream vector start end
-</programlisting>
-        <bridgehead renderas="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 calledby WRITE-SEQUENCE, this argument is guaranteed to be asimple one-dimensional array.</variablelist>
-          </indexterm><indexterm>start
-            <variablelist>a non-negative integer. When a STREAM-WRITE-VECTORmethod is called by WRITE-SEQUENCE, this argument isguaranteed to be no greater than end and not greater thanthe length of vector.</variablelist>
-          </indexterm><indexterm>end
-            <variablelist>a non-negative integer. When a STREAM-WRITE-VECTORmethod is called by WRITE-SEQUENCE, this argument isguaranteed to be no less than end and not greater than thelength of vector.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="CCL--STREAM-DEVICE">
-        <para>CCL::STREAM-DEVICE</para>
-        <informalfigure>stream-device</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::STREAM-DEVICE &mdash; Returns the OS file descriptor associated with a
-given lisp stream.</para>
-        <para>Generic Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-ccl::stream-device
-	  s direction
-</programlisting>
-        <bridgehead renderas="sect3">Method Signatures</bridgehead>
-        <programlisting>
-ccl::stream-device
-	  (s stream) direction => fd
-</programlisting>
-        <bridgehead renderas="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 integerused 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> in the direction given by<literal>direction</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="STREAM-READ-IVECTOR">
-        <para>STREAM-READ-IVECTOR</para>
-        <informalfigure>stream-read-ivector</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>STREAM-READ-IVECTOR &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-read-ivector
-	  stream ivector start-octet max-octets
-</programlisting>
-        <bridgehead renderas="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="sect3">Arguments</bridgehead>
-        <term><indexterm>stream
-            <variablelist>An input stream. The method defined onBUFFERED-INPUT-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="STREAM-WRITE-IVECTOR">
-        <para>STREAM-WRITE-IVECTOR</para>
-        <informalfigure>stream-write-ivector</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>STREAM-WRITE-IVECTOR &mdash;</para>
-        <para>Generic Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-stream-write-ivector stream
-	  ivector start-octet max-octets
-</programlisting>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Writes max-octets octets to stream from ivector, starting at
-start-octet. Returns max-octets.</para>
-        <bridgehead renderas="sect3">Arguments</bridgehead>
-        <term><indexterm>stream
-            <variablelist>An input stream. The method defined onBUFFERED-OUTPUT-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="sect3">Examples</bridgehead>
-        <programlisting>
-;;; Write the contents of a (SIMPLE-ARRAY(UNSIGNED-BYTE 16) 3)
+      <refentry id="f_stream-read-list">
+	<indexterm zone="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="f_stream-write-list">
+	<indexterm zone="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="f_stream-read-vector">
+	<indexterm zone="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="f_stream-write-vector">
+	<indexterm zone="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="f_stream-device">
+	<indexterm zone="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 => 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="f_stream-read-ivector">
+	<indexterm zone="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="f_stream-write-ivector">
+	<indexterm zone="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="linespecific">;;; Write the contents of a (SIMPLE-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))))
@@ -4693,18 +6952,18 @@
 
 ;;; 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 (= (- 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 (= (- 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)))</programlisting>
+	</refsect1>
+      </refentry>
     </sect1>
   </chapter>
@@ -5271,5 +7530,5 @@
 	      <listitem>
 		<para>The argument/return values
-		is <link linkend="arb24">a MACPTR</link>.</para>
+		is <link linkend=""Referencing-and-Using-Foreign-Memory-Addresses">a MACPTR</link>.</para>
 	      </listitem>
 	    </varlistentry>
@@ -5616,256 +7875,675 @@
 
         <sect3 id="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 mostsignificant bit of the byte at that address.) Can be used withSETF.</variablelist>
-            </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="iget-bitfield--Function-">
-          <para>%get-bitfield [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>%get-bitfield ptr bit-offset width</variablelist>
-            </indexterm><indexterm>Description
-              <variablelist>References and returns an unsigned integer composed from thewidth bits found bit-offsetbits from the address encapsulated byptr. (The least significant bit of the result is the value of(%get-bit ptr (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="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 matches int.</variablelist>
-            </indexterm><indexterm>Arguments
-              <variablelist> 
-                <term><indexterm>int
-                    <variablelist>An (unsigned-byte 32)</variablelist>
-                  </indexterm>
-                </term></variablelist>
-            </indexterm>
-          </term>
-        </sect3>
-
-        <sect3 id="iinc-ptr--Function-">
-          <para>%inc-ptr [Function]</para>
-          <term><indexterm>Syntax
-              <variablelist>%inc-ptr ptr &amp;optional (delta 1)</variablelist>
-            </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="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="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="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="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 address 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="iincf-ptr--Macro-">
-          <para>%incf-ptr [Macro]</para>
-          <term><indexterm>Syntax
-              <variablelist>%incf-ptr ptr &amp;optional (delta 1)</variablelist>
-            </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="with-macptrs--Macro-">
-          <para>with-macptrs [Macro]</para>
-          <term><indexterm>Syntax
-              <variablelist>with-macptrs (var expr)* &amp;body body</variablelist>
-            </indexterm><indexterm>Description
-              <variablelist>Executes body in an environment in which each var is boundto a stack-allocated macptr which encapsulates the foreign addressyielded 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="istack-block--Macro-">
-          <para>%stack-block [Macro]</para>
-          <term><indexterm>Syntax
-              <variablelist>%stack-block (var expr)* &amp;body body</variablelist>
-            </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 size expr bytes. Returns whatevervalue(s) body returns.</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="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 length (1+(length string)). Copies the string to this block and appends atrailing 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="with-cstrs--Macro-">
-          <para>with-cstrs [Macro]</para>
-          <term><indexterm>Syntax
-              <variablelist>with-cstrs (var string)* &amp;body body</variablelist>
-            </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="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 -terminated) 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="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>length</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></para>
+	      </listitem>
+	    </varlistentry>
+	  </variablelist>
+	</sect3>
       </sect2>
     </sect1>
@@ -5885,9 +8563,13 @@
         <para>Not surprisingly, different platforms use different database files.</para>
         <para>OpenMCL defines reader macros that consult these databases:</para>
-        <listitem mark="bullet">
-          <variablelist>#$foo looks up the value of the constant definition 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</para>
+	  </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
@@ -6027,170 +8709,253 @@
         <para>To create a new interface directory, "foo", and a set of
         database files in that directory:</para>
-        <varlistentry numeration="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"populate.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.sh"files in the distribution as guidelines.The file might wind up looking something 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="restarts" inheritnum="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="linespecific">? (close (open &#34;ccl:headers;foo;C;populate.sh&#34; :direction :output :
+               if-does-not-exist :create :if-exists :overwrite))</programlisting>
+	  </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="linespecific">#/bin/sh
+h-to-ffi.sh `foo-config -cflags` /usr/include/foo/foo.h</programlisting>
+	  </listitem>
+	</orderedlist>
+
+        <para>Refer to <xref linkend="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="Using-Shared-Libraries">
-      <para>Using Shared Libraries</para>
-
-      <sect2 id="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, 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>
+      <title>Using Shared Libraries</title>
+
+      <sect2 id="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="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="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="Limitations-and-known-bugs--1-">
-        <para>Limitations and known bugs</para>
-        <listitem mark="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 unopenedlibraries, but it's possible to close libraries on which otherlibraries depend.It <emphasis>may</emphasis> be possible to generate moreexplicit dependency information by parsing the output of the Linux lddand ldconfig programs.</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="Darwin-Notes">
-        <para>Darwin Notes
-Darwin shared libraries come in two (basic) flavors:</para>
-        <listitem mark="bullet">
-          <variablelist>"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.</variablelist>
-          <variablelist>"bundles" are intended to serve as applicationextensions; they can be opened multiple times (creating multipleinstances of the 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="The-Interface-Translator">
-      <para>The Interface Translator</para>
-
-      <sect2 id="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 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 )
-<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</emphasis>;<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>
+      <title>The Interface Translator</title>
+
+      <sect2 id="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</emphasis>;<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 and 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="Details--rebuilding-the-CDB-databases--step-by-step">
-        <para>Details: rebuilding the CDB databases, step by step</para>
-        <varlistentry numeration="arabic">
-          <variablelist>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;".</variablelist>
-          <variablelist>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.</variablelist>
-          <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")
@@ -6201,53 +8966,53 @@
 ;;; appear in "ccl:headers;subdir;"
 ;;; (or "ccl:darwin-headers;subdir;" under Darwin)
-</programlisting></variablelist>
-        </varlistentry>
-        <para>PARSE-STANDARD-FFI-FILES accepts a :PREPEND-UNDERSCORES keyword
-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="Case-sensitivity-of-foreign-names-in-OpenMCL">
-      <para>Case-sensitivity of foreign names in OpenMCL</para>
-
-      <sect2 id="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 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>
+      <title>Case-sensitivity of foreign names in OpenMCL</title>
+
+      <sect2 id="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="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"
@@ -6260,46 +9025,63 @@
 
       <sect2 id="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 (keywords)
-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="bullet">
-          <variablelist>All instances of < and > in the symbol's pname arebalanced and don't nest.</variablelist>
-          <variablelist>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 casein which they were written.</variablelist>
-          <variablelist>Alphabetic characters that appear within angle brackets aremapped to upper-case, again regardless of how they were written orinterned.</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 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>
+	<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="Examples--1-">
-        <para>Examples</para>
+        <title>Examples</title>
         <programlisting>
 ;;; Allocate a record of type "window".
@@ -6307,7 +9089,7 @@
 ;;; 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>
@@ -6315,16 +9097,18 @@
 
     <sect1 id="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
@@ -6333,4 +9117,5 @@
     printf("Entered %s:\n", __FUNCTION__);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
 }
 
@@ -6341,4 +9126,5 @@
     printf("Data In: %d\n", (signed int)data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
@@ -6350,56 +9136,61 @@
     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, 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><inlinemediaobject name="arb36"></inlinemediaobject></para>
-      <para>This code is compiled into a dynamic library on OS X 10.3.4 with 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, 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>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
@@ -6408,50 +9199,49 @@
 
 ? 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 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 :</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="m_external-call"/>:</para>
       <programlisting>
 
 ? (external "_void_void_test")
-#<EXTERNAL-ENTRY-POINT "_void_void_test" (#x000CFDF8) /Users/andewl/openmcl/libtypetest.dylib #x638EDF6>
+#&lt;EXTERNAL-ENTRY-POINT "_void_void_test" (#x000CFDF8) /Users/andewl/openmcl/libtypetest.dylib #x638EDF6>
 
 ? (external "_sc_sc_test")
-#<EXTERNAL-ENTRY-POINT "_sc_sc_test" (#x000CFE50) /Users/andewl/openmcl/libtypetest.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/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>
+#&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>.</para>
-      <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>
 
@@ -6460,16 +9250,9 @@
 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>
@@ -6482,11 +9265,10 @@
 -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>
 
@@ -6497,6 +9279,6 @@
 -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>
 
@@ -6521,19 +9303,20 @@
 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 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>
+      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>
@@ -6545,4 +9328,5 @@
     printf("Data In: %d\n", data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
@@ -6554,4 +9338,5 @@
     printf("Data In: %ld\n", data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
@@ -6563,4 +9348,5 @@
     printf("Data In: %lld\n", data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
@@ -6572,4 +9358,5 @@
     printf("Data In: %e\n", data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
@@ -6581,4 +9368,5 @@
     printf("Data In: %e\n", data);
     printf("Exited  %s:\n", __FUNCTION__);
+    fflush(stdout);
     return data;
 }
@@ -6590,6 +9378,7 @@
     -install_name ./libtypetest.dylib
 </programlisting>
-      <para>Now, restart OpenMCL.  This step is required because OpenMCL cannot
-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>
@@ -6598,5 +9387,5 @@
 
 ? (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)
@@ -6606,5 +9395,5 @@
 -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:
@@ -6620,9 +9409,10 @@
 -973891578912
 </programlisting>
-      <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>
+      <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>
 
@@ -6633,9 +9423,11 @@
 Exited  sl_sl_test:
 -974957576192
-</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>
+      <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>
 
@@ -6643,5 +9435,5 @@
 
 ? (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)
@@ -6656,5 +9448,5 @@
 Exited  d_d_test:
 -1.256791D+290
-</programlisting>
+      </programlisting>
       <para>Notice that the number ends with "...e+11" for the single-float,
 and "...d+290" for the
@@ -6670,82 +9462,81 @@
 
       <sect2 id="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="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 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>
+      <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)
@@ -6753,5 +9544,5 @@
   int i, t;
 
-  for(i=0; i<dataobjs/2; i++)
+  for(i=0; i&lt;dataobjs/2; i++)
     {
       t = *(data+i);
@@ -6766,5 +9557,5 @@
   int i;
 
-  for(i=0; i<ptrobjs/2; i++)
+  for(i=0; i&lt;ptrobjs/2; i++)
     {
       t = *(ptrs+i);
@@ -6782,24 +9573,25 @@
   reverse_int_array(*(ptrs+1), 4);
 }
-</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>
+      <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 ./libptrtest.dylib
-</programlisting>
+      </programlisting>
       <para>If that command doesn't make sense to you, feel free to go back
 and read about it at .</para>
@@ -6825,13 +9617,13 @@
 DISPOSE-HEAP-IVECTOR
 </programlisting>
-      <para>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>
+      <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
@@ -6843,5 +9635,5 @@
 ;   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
@@ -6849,21 +9641,17 @@
 
 ? 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
@@ -6885,6 +9673,6 @@
 #(3 4 5)
 </programlisting>
-      <para>In addition, the <literal>macptr</literal> allows direct access 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)
@@ -6906,14 +9694,14 @@
 a
 #(6 4 7)
-</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>
+      <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
@@ -6921,8 +9709,8 @@
 
 ? 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
@@ -6930,16 +9718,15 @@
 
 ? 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 moving
-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
@@ -6963,60 +9750,57 @@
 </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 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>
+      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>
@@ -7043,789 +9827,1367 @@
       (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 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>
+      </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="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="The-Foreign-Function-Interface-Dictionary">
-      <para>The Foreign-Function-Interface Dictionary</para>
-
-      <sect2 id="DEF-FOREIGN-TYPE">
-        <para>DEF-FOREIGN-TYPE</para>
-        <informalfigure>def-foreign-type</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>DEF-FOREIGN-TYPE &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    def-foreign-type name foreign-type-spec
-
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>NIL or a keyword; the keyword may containescaping constructs (see ).</variablelist>
-          </indexterm><indexterm>foreign-type-spec
-            <variablelist>A foreign type specifier, whose syntax is (loosely)defined above.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="MAKE-RECORD">
-        <para>MAKE-RECORD</para>
-        <informalfigure>make-record</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>MAKE-RECORD &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    make-record typespec
-	    &amp;rest initforms => result
-
-</programlisting>
-        <bridgehead renderas="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</literal>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 the address of anewly-allocated record on the foreign heap.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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 possible 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="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="RLET">
-        <para>RLET</para>
-        <informalfigure>rlet</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>RLET &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    rlet (var typespec &amp;rest initforms)*
-	    &amp;body body
-
-</programlisting>
-        <bridgehead renderas="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="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="RLETZ">
-        <para>RLETZ</para>
-        <informalfigure>rletz</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>RLETZ &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    rletz (var typespec &amp;rest initforms)*
-	    &amp;body body
-
-</programlisting>
-        <bridgehead renderas="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</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="PREF">
-        <para>PREF</para>
-        <informalfigure>pref</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>PREF &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    pref ptr accessor-form
-
-</programlisting>
-        <bridgehead renderas="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="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="OPEN-SHARED-LIBRARY">
-        <para>OPEN-SHARED-LIBRARY</para>
-        <informalfigure>open-shared-library</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>OPEN-SHARED-LIBRARY &mdash; Asks the operating system to load a shared library
-for OpenMCL to use.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    open-shared-library name => library
-
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>A SIMPLE-STRING which is presumed to be the so-name ofor a filesystem path to the library.</variablelist>
-          </indexterm><indexterm>library
-            <variablelist>An object of type SHLIB which describes thelibrary denoted by <literal>name</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="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: undefined 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="m_def-foreign-type">
+	<indexterm zone="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="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="m_make-record">
+	<indexterm zone="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 => 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="arb25"/>), which is undesireable
+	    because it's large.
+	  </para>
+	</refsect1>
+      </refentry>
+
+      <refentry id="m_rlet">
+	<indexterm zone="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="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="Referencing-and-Using-Foreign-Memory-Addresses">a MACPTR</link> encapsulating the
+	  address of a stack-allocated foreign memory block, allocated and
+	  initialized from typespec and initforms as per
+	  <xref linkend="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="m_rletz">
+	<indexterm zone="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="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="m_pref">
+	<indexterm zone="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="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="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="f_open-shared-library">
+	<indexterm zone="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 => 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="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/libgtk.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 #x3046FE46&#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="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="CLOSE-SHARED-LIBRARY">
-        <para>CLOSE-SHARED-LIBRARY</para>
-        <informalfigure>close-shared-library</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CLOSE-SHARED-LIBRARY &mdash; Stops using a shared library, informing the operating
-system that it can be unloaded if appropriate.</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    close-shared-library library &amp;key
-	  completely
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>library
-            <variablelist>either an object of type SHLIB, or a string whichdesignates one by its so-name.</variablelist>
-          </indexterm><indexterm>completely
-            <variablelist>a boolean.  The default is T.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="EXTERNAL">
-        <para>EXTERNAL</para>
-        <informalfigure>external</informalfigure>
-        <bridgehead renderas="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="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    external name => entry
-
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>a simple-string which names an external symbol.Case-sensitive.</variablelist>
-          </indexterm><indexterm>entry
-            <variablelist>an object of type EXTERNAL-ENTRY-POINT which maintainsthe address of the foreign symbol named by<literal>name</literal>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="iFF-CALL">
-        <para>%FF-CALL</para>
-        <informalfigure>%ff-call</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>%FF-CALL &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    %ff-call entrypoint
-	    {arg-type-keyword arg}* &amp;optional result-type-keyword
-
-</programlisting>
-        <bridgehead renderas="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, describedabove</variablelist>
-          </indexterm><indexterm>arg
-            <variablelist>A lisp value of type indicated by the correspondingarg-type-keyword</variablelist>
-          </indexterm><indexterm>result-type-keyword
-            <variablelist>One of the foreign argument-type keywords, describedabove</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="FF-CALL">
-        <para>FF-CALL</para>
-        <informalfigure>ff-call</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>FF-CALL &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    ff-call entrypoint
-	    {arg-type-specifier arg}* &amp;optional result-type-specifier
-
-</programlisting>
-        <bridgehead renderas="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, describedabove, or an equivalent foreigntype specifier (see ).</variablelist>
-          </indexterm><indexterm>arg
-            <variablelist>A lisp value of type indicated by the correspondingarg-type-specifier</variablelist>
-          </indexterm><indexterm>result-type-specifier
-            <variablelist>One of the foreign argument-type keywords, describedabove, or an equivalent foreigntype specifier (see ).</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="iREFERENCE-EXTERNAL-ENTRY-POINT">
-        <para>%REFERENCE-EXTERNAL-ENTRY-POINT</para>
-        <informalfigure>%reference-external-entry-point</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>%REFERENCE-EXTERNAL-ENTRY-POINT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    %reference-external-entry-point eep
-
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>eep
-            <variablelist>An EXTERNAL-ENTRY-POINT, as obtained by the EXTERNALmacro.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="EXTERNAL-CALL">
-        <para>EXTERNAL-CALL</para>
-        <informalfigure>external-call</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>EXTERNAL-CALL &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    external-call name
-	    {arg-type-specifier arg}* &amp;optional result-type-specifier
-
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>A lisp string. See external, above.</variablelist>
-          </indexterm><indexterm>arg-type-specifer
-            <variablelist>One of the foreign argument-type keywords, describedabove, or an equivalent foreigntype specifier (see ).</variablelist>
-          </indexterm><indexterm>arg
-            <variablelist>A lisp value of type indicated by the correspondingarg-type-specifier</variablelist>
-          </indexterm><indexterm>result-type-specifier
-            <variablelist>One of the foreign argument-type keywords, describedabove, or an equivalent foreigntype specifier (see ).</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="FOREIGN-SYMBOL-ENTRY">
-        <para>FOREIGN-SYMBOL-ENTRY</para>
-        <informalfigure>foreign-symbol-entry</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>FOREIGN-SYMBOL-ENTRY &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    foreign-symbol-entry name
-
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>A lisp string.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="FOREIGN-SYMBOL-ADDRESS">
-        <para>FOREIGN-SYMBOL-ADDRESS</para>
-        <informalfigure>foreign-symbol-address</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>FOREIGN-SYMBOL-ADDRESS &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    foreign-symbol-address name
-
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>A lisp string.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="DEFCALLBACK">
-        <para>DEFCALLBACK</para>
-        <informalfigure>defcallback</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>DEFCALLBACK &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    defcallback name
-	    ({arg-type-specifier var}* &amp;optional result-type-specifier)
-	    &amp;body body
-
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>A symbol which can be made into a special variable</variablelist>
-          </indexterm><indexterm>arg-type-specifer
-            <variablelist>One of the foreign argument-type keywords, describedabove, or an equivalent foreigntype specifier (see ).In addition, if the keyword:WITHOUT-INTERRUPTS is specified, the callback will beexecuted with lisp interrupts disabled if the correspondingvar is non-NIL. If :WITHOUT-INTERRUPTS is specified morethan once, the rightmost instance wins.</variablelist>
-          </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="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="SHARP-UNDERSCORE">
-        <para>SHARP-AMPERSAND</para>
-        <informalfigure>#_</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>#_ &mdash;</para>
-        <para>Reader Macro</para>
-        <bridgehead renderas="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="SHARP-AMPERSAND">
-        <para>SHARP-AMPERSAND</para>
-        <informalfigure>SHARP-AMPERSAND</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>#&amp; &mdash;</para>
-        <para>Reader Macro</para>
-        <bridgehead renderas="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 used 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 header 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="USE-INTERFACE-DIR">
-        <para>USE-INTERFACE-DIR</para>
-        <informalfigure>use-interface-dir</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>USE-INTERFACE-DIR &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    use-interface-dir dir-id
-
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>dir-id
-            <variablelist>A keyword whose pname, mapped to lower case, names asubdirectory of "ccl:headers;" (or"ccl:darwin-headers;")</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="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="UNUSE-INTERFACE-DIR">
-        <para>UNUSE-INTERFACE-DIR</para>
-        <informalfigure>unuse-interface-dir</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>UNUSE-INTERFACE-DIR &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    unuse-interface-dir dir-id
-
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>dir-id
-            <variablelist>A keyword whose pname, mapped to lower case, names asubdirectory of "ccl:headers;" (or"ccl:darwin-headers;")</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="TERMINATE-WHEN-UNREACHABLE">
-        <para>TERMINATE-WHEN-UNREACHABLE</para>
-        <informalfigure>terminate-when-unreachable</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>TERMINATE-WHEN-UNREACHABLE &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    terminate-when-unreachable object
-
-</programlisting>
-        <bridgehead renderas="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>.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="sect3">Example</bridgehead>
-        <programlisting>
+? (external &#34;gtk_main&#34;)
+#&#60;EXTERNAL-ENTRY-POINT &#34;gtk_main&#34; {unresolved} libgtk.so #x3046FE46&#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="f_close-shared-library">
+	<indexterm zone="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="m_external">
+	<indexterm zone="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 => 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="f_Pff-call">
+	<indexterm zone="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="m_ff-call">
+	<indexterm zone="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="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="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="f_Preference-external-entry-point">
+	<indexterm zone="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="m_external-call">
+	<indexterm zone="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="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="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="f_foreign-symbol-entry">
+	<indexterm zone="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="f_foreign-symbol-address">
+	<indexterm zone="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="Referencing-and-Using-Foreign-Memory-Addresses">a
+	  MACPTR</link>, else returns NIL.</para>
+	</refsect1>
+      </refentry>
+
+      <refentry id="m_defcallback">
+	<indexterm zone="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="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="rm_sharpsign-underscore">
+	<indexterm zone="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.</para>
+	  
+	  <para>Does a lookup on that symbol
+	  in <link linkend="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="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="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="linespecific">(with-cstrs ((format-string &#34;the answer is: %d&#34;))
+  (#_printf format-string :int answer))</programlisting>
+	</refsect1>
+      </refentry>
+
+      <refentry id="rm_sharpsign-questionmark">
+	<indexterm zone="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.</para>
+	  
+	  <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="f_use-interface-dir">
+	<indexterm zone="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="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="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="f_unuse-interface-dir">
+	<indexterm zone="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="f_terminate-when-unreachable">
+	<indexterm zone="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="linespecific">
 (defclass resource-wrapper ()
   ((resource :accessor resource)))
@@ -7836,43 +11198,52 @@
 (defmethod ccl:terminate ((x resource-wrapper))
   (when (resource x)
-    (deallocate (resource x))))
-</programlisting>
-        <bridgehead renderas="sect3">See Also</bridgehead>
-        <para role="continues">Tutorial: Allocating Foreign Data on the Lisp Heap</para>
-      </sect2>
+    (deallocate (resource x))))</programlisting>
+	</refsect1>
+
+	<refsect1>
+	  <title>See Also</title>
+
+	  <simplelist type="inline">
+	    <member><xref linkend="arb35"/></member>
+	  </simplelist>
+	</refsect1>
+
+      </refentry>
+
     </sect1>
   </chapter>
 
   <chapter id="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="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
@@ -7914,21 +11285,21 @@
 
     <sect1 id="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
@@ -7941,5 +11312,5 @@
 
 ? (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
@@ -7967,5 +11338,5 @@
                    :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
@@ -7975,18 +11346,18 @@
 
     <sect1 id="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>
@@ -8014,89 +11385,63 @@
 
       <sect2 id="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 that
-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 between
-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="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 = [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="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 two
-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
@@ -8135,5 +11480,6 @@
 
       <sect2 id="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
@@ -8163,23 +11509,22 @@
 
       <sect2 id="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)))
@@ -8187,66 +11532,66 @@
   (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="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, 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>
+      <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)
@@ -8255,22 +11600,23 @@
 </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="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 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>
+	<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)
@@ -8281,13 +11627,14 @@
 </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="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)
@@ -8296,32 +11643,31 @@
                    :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="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
@@ -8333,30 +11679,27 @@
   (: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))
@@ -8367,12 +11710,11 @@
           (* 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>
@@ -8386,13 +11728,13 @@
              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))
@@ -8403,20 +11745,21 @@
           (- (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 following 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)
@@ -8425,82 +11768,63 @@
 </programlisting>
       <sect2 id="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="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="1">
-          <tbody colwidth="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 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>
+      "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="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 your
-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)
@@ -8518,286 +11842,273 @@
 (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="Using-OpenMCL-with-Mac-OS-X--the-Darwin-Kernel--and-the-Cocoa-GUI-API">
-    <para>Using OpenMCL with Mac OS X, the Darwin Kernel,  and the Cocoa GUI API</para>
-
-    <sect1 id="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 OpenMCL under LinuxPPC should apply to using it under Darwin/MacOS X. There are some differences between the platforms, and these differences are sometimes exposed in the implementation.</para>
-
-      <sect2 id="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 data 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, .pfsl 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="Platform-specific-notes">
+    <title>Platform-specific notes</title>
+      
+
+    <sect1 id="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="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 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>
+	</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="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 LinuxPPC,
-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="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="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 "bundles"; 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="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="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="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 (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>
+      <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="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="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="1">
-            <tbody colwidth="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="vert" columns="1">
+	  <member><xref linkend="m_class"/></member>
+	  <member><xref linkend="m_selector"/></member>
+	  <member><xref linkend="m_define-objc-method"/></member>
+	  <member><xref linkend="m_define-objc-class-method"/></member>
+	</simplelist>
       </sect2>
 
       <sect2 id="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 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>
+	<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,
@@ -8807,21 +12118,22 @@
 
       <sect2 id="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="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 OpenMCL icon
 in the ccl directory, to quickly start your program.</para>
@@ -8856,458 +12168,915 @@
 
     <sect1 id="Recommended-Reading">
-      <para>Recommended Reading</para>
-      <term><indexterm>Cocoa Documentation
-          <variablelist>This is the top page for all of Apple's documentation 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 references; itcovers all of the basics, except for GUI programming.  This isa reference, 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.</variablelist>
-        </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="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="http://developer.apple.com/documentation/Cocoa/Reference/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="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/ObjC_classic/index.html">Application Kit Reference for Objective-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="http://developer.apple.com/documentation/index.html">Apple 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="Operating-System-Dictionary">
-      <para>Operating-System Dictionary</para>
-
-      <sect2 id="CCL--GETENV">
-        <para>CCL::GETENV</para>
-        <informalfigure>getenv</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::GETENV &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-getenv name => value
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>a string which is the name of an existingenvironment variable;case-sensitive</variablelist>
-          </indexterm><indexterm>value
-            <variablelist>if there is an environment variable named<literal>name</literal>, its value, as a string; if thereis not, NIL</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="CCL--SETENV">
-        <para>CCL::SETENV</para>
-        <informalfigure>setenv</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::SETENV &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-setenv name value => errno
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>name
-            <variablelist>a string which is the name of a new or existingenvironment 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</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="CCL--CURRENT-DIRECTORY-NAME">
-        <para>CCL::CURRENT-DIRECTORY-NAME</para>
-        <informalfigure>current-directory-name</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::CURRENT-DIRECTORY-NAME &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-current-directory-name
-	  => path
-</programlisting>
-        <bridgehead renderas="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="sect3">Description</bridgehead>
-        <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>
-      </sect2>
-
-      <sect2 id="CCL--GETUID">
-        <para>CCL::GETUID</para>
-        <informalfigure>getuid</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::GETUID &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-getuid => uid
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>uid
-            <variablelist>a non-negative integer, identifying a specific useraccount as defined in the OS user database</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns the ("real") user ID of the current user.</para>
-      </sect2>
-
-      <sect2 id="CCL--SETUID">
-        <para>CCL::SETUID</para>
-        <informalfigure>setuid</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::SETUID &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-setuid uid => errno
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>uid
-            <variablelist>a non-negative integer, identifying a specific useraccount 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</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="CCL--SETGID">
-        <para>CCL::SETGID</para>
-        <informalfigure>setgid</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::SETGID &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-setgid gid => errno
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>gid
-            <variablelist>a non-negative integer, identifying a specificgroup 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</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="CCL--GETPID">
-        <para>CCL::GETPID</para>
-        <informalfigure>getpid</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::GETPID &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-getpid => pid
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>pid
-            <variablelist>a non-negative integer, identifying an OS process</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns the ID of the OpenMCL OS process.</para>
-      </sect2>
-
-      <sect2 id="CCL--GET-USER-HOME-DIR">
-        <para>CCL::GET-USER-HOME-DIR</para>
-        <informalfigure>get-user-home-dir</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::GET-USER-HOME-DIR &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-get-user-home-dir
-	  uid => path
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>uid
-            <variablelist>a non-negative integer, identifying a specific useraccount 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="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="CCL--OS-COMMAND">
-        <para>CCL::OS-COMMAND</para>
-        <informalfigure>os-command</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::OS-COMMAND &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-os-command command-line
-	  => exit-code
-</programlisting>
-        <bridgehead renderas="sect3">Values</bridgehead>
-        <term><indexterm>command-line
-            <variablelist>a string, obeying all the whitespace andescapingconventions 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="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="sect3">Notes</bridgehead>
-        <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>
-      </sect2>
-
-      <sect2 id="CCL----CLASS">
-        <para>CCL::@CLASS</para>
-        <informalfigure>@class</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::@CLASS &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-@class class-name
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>class-name
-            <variablelist>a string which denotes an existing class name, or asymbol which can be mapped to such a string via the standardname-mapping conventions for class names</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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, because
-find-class now works on ObjC classes.  It is described here
-only because some old code still uses it.</para>
-      </sect2>
-
-      <sect2 id="CCL----SELECTOR">
-        <para>CCL::@SELECTOR</para>
-        <informalfigure>@selector</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::@SELECTOR &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-@selector string
-</programlisting>
-        <bridgehead renderas="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="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="CCL--DEFINE-OBJC-METHOD">
-        <para>CCL::DEFINE-OBJC-METHOD</para>
-        <informalfigure>define-objc-method</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::DEFINE-OBJC-METHOD &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-define-objc-method
-	    (selector class-name) &amp;body body
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>selector
-            <variablelist>either a string which represents the name of theselector or a list which describ+es the method's returntype, selector components, and argument types (see below.)If the first form is used, then the first form in the bodymust be a list which describes the selector's argumenttypes and return value type, as per DEFCALLBACK.</variablelist>
-          </indexterm><indexterm>class-name
-            <variablelist>either a string which names an existing ObjC classname 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="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="CCL--DEFINE-OBJC-CLASS-METHOD">
-        <para>CCL::DEFINE-OBJC-CLASS-METHOD</para>
-        <informalfigure>define-objc-class-method</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::DEFINE-OBJC-CLASS-METHOD &mdash;</para>
-        <para>Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-define-objc-class-method
-	    (selector class-name) &amp;body body
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <para>As per DEFINE-OBJC-METHOD</para>
-        <bridgehead renderas="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="bullet">
-          <variablelist>a non-keyword symbol, which can be mapped to a selector stringfor a parameterless method according to the standard name-mappingconventions for method selectors.</variablelist>
-          <variablelist>a list of alternating keywords and variable/type specifiers,where the set of keywords can be mapped to a selector string for aparameteriezed method according to the standard name-mappingconventions for method selectors and each variable/type-specifier iseither a variable name (denoting a value of type :ID) or a list whoseCAR is a variable name and whose CADR is the correspondingargument's foreign type specifier.</variablelist>
-        
-        </listitem>
-      </sect2>
-
-      <sect2 id="CCL--ALTERNATE-LINE-TERMINATOR-">
-        <para>CCL:*ALTERNATE-LINE-TERMINATOR*</para>
-        <informalfigure>*alternate-line-terminator*</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL:*ALTERNATE-LINE-TERMINATOR* &mdash;</para>
-        <para>Variable</para>
-        <bridgehead renderas="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 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-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="iEXTERNAL-FORMAT">
-        <para>:EXTERNAL-FORMAT</para>
-        <informalfigure>:external-format</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>:EXTERNAL-FORMAT &mdash;</para>
-        <para>Keyword Argument</para>
-        <bridgehead renderas="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 the 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 written
-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.</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'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 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>
-      </sect2>
-
-      <sect2 id="CCL--DEFAULT-EXTERNAL-FORMAT-">
-        <para>CCL:*DEFAULT-EXTERNAL-FORMAT*</para>
-        <informalfigure>*default-external-format*</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL:*DEFAULT-EXTERNAL-FORMAT* &mdash;</para>
-        <para>Variable</para>
-        <bridgehead renderas="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 translation
-could have undesirable consequences, the initial value of this variable
-in OpenMCL is :UNIX.</para>
-      </sect2>
-
-      <sect2 id="CCL--NS-LISP-STRING">
-        <para>CCL::NS-LISP-STRING</para>
-        <informalfigure>ns-lisp-string</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CCL::NS-LISP-STRING &mdash;</para>
-        <para>Class</para>
-        <bridgehead renderas="sect3">Superclasses</bridgehead>
-        <para>NS:NS-STRING</para>
-        <bridgehead renderas="sect3">Initargs</bridgehead>
-        <term><indexterm>:string
-            <variablelist>a Lisp string which is to be the content ofthe newly-created ns-lisp-string.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="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="f_getenv">
+	<indexterm zone="f_getenv">
+	  <primary>getenv</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::GETENV</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>getenv</function> name => 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="f_setenv">
+	<indexterm zone="f_setenv">
+	  <primary>setenv</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::SETENV</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>setenv</function> name value => 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="f_current-directory-name">
+	<indexterm zone="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>
+	  => 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="f_getuid">
+	<indexterm zone="f_getuid">
+	  <primary>getuid</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::GETUID</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>getuid</function> => 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="f_setuid">
+	<indexterm zone="f_setuid">
+	  <primary>setuid</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::SETUID</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>setuid</function> uid => 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="f_setgid">
+	<indexterm zone="f_setgid">
+	  <primary>setgid</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::SETGID</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>setgid</function> gid => 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="f_getpid">
+	<indexterm zone="f_getpid">
+	  <primary>getpid</primary>
+	</indexterm>
+
+	<refnamediv>
+	  <refname>CCL::GETPID</refname>
+	  <refpurpose></refpurpose>
+	  <refclass>Function</refclass>
+	</refnamediv>
+
+	<refsynopsisdiv>
+	  <synopsis><function>getpid</function> => 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="f_get-user-home-dir">
+	<indexterm zone="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 => 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="f_os-command">
+	<indexterm zone="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
+	  => 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="m_class">
+	<indexterm zone="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="m_selector">
+	  <indexterm zone="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="m_define-objc-method">
+	  <indexterm zone="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="m_define-objc-class-method">
+	  <indexterm zone="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="v_alternate-line-terminator">
+	  <indexterm zone="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 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&#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-terminated
+	    (Unix) text file contains embedded #\Return characters, and this
+	    mechanism isn&#39;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&#39;t change
+	    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="k_external-format">
+	  <indexterm zone="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-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 the 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 written
+	    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.</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&#39;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&#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&#39;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="v_default-external-format">
+	  <indexterm zone="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 interpreted
+	    as described above.</para>
+	    
+	    <para>Because there&#39;s some risk that unsolicited newline translation
+	    could have undesirable consequences, the initial value of this variable
+	    in OpenMCL is :UNIX.</para>
+	  </refsect1>
+	</refentry>
+
+	<refentry id="c_ns-lisp-string">
+	  <indexterm zone="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="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="linespecific">? (ccl::send *the-string* 'dealloc)</programlisting>
+
+	    <para>
+	      You may wish to use an <function>unwind-protect</function>
+	      form to ensure that this happens:
+	    </para>
+
+	    <programlisting format="linespecific"
+>(let (*the-string*)
   (unwind-protect (progn (setq *the-string*
                                (make-instance 'ccl::ns-lisp-string
@@ -9316,50 +13085,61 @@
                                  (ccl::send *the-string* 'length)))
     (when *the-string*
-      (ccl::send *the-string* 'dealloc))))
-</programlisting>
-        <bridgehead renderas="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="Understanding-and-Configuring-the-Garbage-Collector">
-    <para>Understanding and Configuring the Garbage Collector</para>
+    <title>Understanding and Configuring the Garbage Collector</title>
 
     <sect1 id="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 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>
+      <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
@@ -9370,476 +13150,684 @@
 
     <sect1 id="The-Ephemeral-GC">
-      <para>The Ephemeral GC
-For many programs, the following observations are true to a very
-large degree:</para>
-      <varlistentry numeration="arabic">
-        <variablelist>Most heap-allocated objects have very short lifetimes ("areephemeral"): they become inaccessible soon after they're created.</variablelist>
-        <variablelist>Most non-ephemeral objects have very long lifetimes: it'srarely productive for the GC to consider reclaiming them, sinceit's rarely able to do so. (An object that's survived a largenumber of GCs is likely to survive the next one. That's not alwaystrue of course, but it's a reasonable heuristic.)</variablelist>
-        <variablelist>It's relatively rare for an old object to be destructivelymodified (via SETF) so that it points to a new one, therefore mostreferences to newly-created objects can be found in the stacks andregisters of active threads. It's not generally necessary to scanthe entire heap to find references to new objects (or to prove thatsuch references don't exists), though it is necessary to keeptrack of the (hopefully exceptional) cases where old objects aremodified to point at new ones.</variablelist>
-      </varlistentry>
-      <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>
+      <title>The Ephemeral GC</title>
+      <para>For many programs, the following observations are true to
+      a very large degree:</para>
+
+      <orderedlist continuation="restarts" inheritnum="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="restarts" inheritnum="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="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 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>
+      <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="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 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>
+      <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="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="Garbage-Collection-Dictionary">
-      <para>Garbage-Collection Dictionary</para>
-
-      <sect2 id="LISP-HEAP-GC-THRESHOLD">
-        <para>LISP-HEAP-GC-THRESHOLD</para>
-        <informalfigure>lisp-heap-gc-threshold</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>LISP-HEAP-GC-THRESHOLD &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-lisp-heap-gc-threshold
-</programlisting>
-        <bridgehead renderas="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="SET-LISP-HEAP-GC-THRESHOLD">
-        <para>SET-LISP-HEAP-GC-THRESHOLD</para>
-        <informalfigure>set-lisp-heap-gc-threshold</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SET-LISP-HEAP-GC-THRESHOLD &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    lisp-heap-gc-threshold new-threshold
-
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>new-value
-            <variablelist>The requested new lisp-heap-gc-threshold.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="USE-LISP-HEAP-GC-THRESHOLD">
-        <para>USE-LISP-HEAP-GC-THRESHOLD</para>
-        <informalfigure>use-lisp-heap-gc-threshold</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>USE-LISP-HEAP-GC-THRESHOLD &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-
-	    use-lisp-heap-gc-threshold
-
-</programlisting>
-        <bridgehead renderas="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="EGC">
-        <para>EGC</para>
-        <informalfigure>egc</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>EGC &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-egc arg
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>arg
-            <variablelist>a generalized boolean</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="EGC-ENABLED-P">
-        <para>EGC-ENABLED-P</para>
-        <informalfigure>egc-enabled-p</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>EGC-ENABLED-P &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-egc-enabled-p
-</programlisting>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns T if the EGC was enabled at the time of the call,
-NIL otherwise.</para>
-      </sect2>
-
-      <sect2 id="EGC-ACTIVE-P">
-        <para>EGC-ACTIVE-P</para>
-        <informalfigure>egc-active-p</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>EGC-ACTIVE-P &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-egc-active-p
-</programlisting>
-        <bridgehead renderas="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="EGC-CONFIGURATION">
-        <para>EGC-CONFIGURATION</para>
-        <informalfigure>egc-configuration</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>EGC-CONFIGURATION &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-egc-configuration
-</programlisting>
-        <bridgehead renderas="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="CONFIGURE-EGC">
-        <para>CONFIGURE-EGC</para>
-        <informalfigure>configure-egc</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>CONFIGURE-EGC &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-configure-egc
+      <title>Garbage-Collection Dictionary</title>
+
+      <refentry id="f_lisp-heap-gc-threshold">
+	<indexterm zone="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="f_set-lisp-heap-gc-threshold">
+	<indexterm zone="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="f_use-lisp-heap-gc-threshold">
+	<indexterm zone="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="f_egc">
+	<indexterm zone="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="f_egc-enabled-p">
+	<indexterm zone="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="f_egc-active-p">
+	<indexterm zone="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="f_egc-configuration">
+	<indexterm zone="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="f_configure-gcc">
+	<indexterm zone="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="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>generation-0-size
-            <variablelist>the requested threshold size of the youngestgeneration, in kilobytes</variablelist>
-          </indexterm><indexterm>generation-1-size
-            <variablelist>the requested threshold size of the middle generation,in kilobytes</variablelist>
-          </indexterm><indexterm>generation-2-size
-            <variablelist>the requested threshold size of the oldest generation,in kilobytes</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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 earlier
-versions.)</para>
-      </sect2>
-
-      <sect2 id="GC-RETAIN-PAGES">
-        <para>GC-RETAIN-PAGES</para>
-        <informalfigure>gc-retain-pages</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>GC-RETAIN-PAGES &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-gc-retain-pages arg
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>arg
-            <variablelist>a generalized boolean</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="GC-RETAINING-PAGES">
-        <para>GC-RETAINING-PAGES</para>
-        <informalfigure>gc-retaining-pages</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>GC-RETAINING-PAGES &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-gc-retaining-pages
-</programlisting>
-        <bridgehead renderas="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="f_gc-retain-pages">
+	<indexterm zone="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="f_gc-retaining-pages">
+	<indexterm zone="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="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="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="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 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>
+	<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="Exception-contexts-comma---and-exception-handling-in-general">
-        <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 in each
 other's way, a signal handler is entered with all signals blocked.
@@ -9859,90 +13847,111 @@
 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 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>
+        <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="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="PC-lusering">
-        <para>PC-luseringIt'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>
-        <listitem mark="bullet">
-          <variablelist>On both PPC and x86-64 platforms, consing isn't fully atomic.It takes at least a few instructions to allocate an object in memory(and slap a header 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 fully initialized at the point in time that theinterrupt occurred.  (There are actually a few different states ofpartial initialization)</variablelist>
-          <variablelist>On the PPC, the common act of building a lisp control stack frameinvolves allocating a four-word frame and storing three register valuesinto that frame.  (The fourth word - the back pointer to the previousframe - is automatically set when the frame is allocated.)  The previouscontents of those three words are unknown (there might have been aforeign stack frame at the 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.</variablelist>
-          <variablelist>There are similar problems with the initialization of temp stackframes on the PPC.  (Allocation and initialization doesn't happenatomically, and the newly allocated stack memory may have undefinedcontents.)</variablelist>
-          <variablelist>'s write barrier has to be implemented atomically (i.e.,both an intergenerational store and the update of a correspondingreference 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 takes at least a few instructions to allocate an object in memory(and slap a header 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 fully 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 frameinvolves allocating a four-word frame and storing three register valuesinto that frame.  (The fourth word - the back pointer to the previousframe - is automatically set when the frame is allocated.)  The previouscontents of those three words are unknown (there might have been aforeign stack frame at the 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.</para>
+</listitem>
+          <listitem>
+<para>There are similar problems with the initialization of temp stackframes on the PPC.  (Allocation and initialization doesn't happenatomically, and the newly allocated stack memory may have undefinedcontents.)</para>
+</listitem>
+          <listitem>
+<para>'s write barrier has to be implemented atomically (i.e.,both an intergenerational store and the update of a correspondingreference bit has to happen 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 sequences is
 small, and fortunately it's fairly easy for the interrupting thread
@@ -9962,285 +13971,619 @@
 
     <sect1 id="Register-usage-and-tagging">
-      <para>Register usage and tagging</para>
+      <title>Register usage and tagging</title>
 
       <sect2 id="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 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>
+	<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="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 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 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 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>
+	<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="Register-and-stack-usage-conventions">
-        <para>Register and stack usage conventions</para>
+        <title>Register and stack usage conventions</title>
 
         <sect3 id="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="bullet">
-            <variablelist>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."</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 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.</variablelist>
-            <variablelist>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.</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="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 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>
+	  <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 involves:</para>
-          <listitem mark="bullet">
-            <variablelist>(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.</variablelist>
-            <variablelist>(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.)</variablelist>
-            <variablelist>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.)</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 involves:</para>
-          <listitem mark="bullet">
-            <variablelist>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.)</variablelist>
-            <variablelist>9 dedicated registers
-              <listitem mark="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 issometimes convenient and avoids asymmetry.</variablelist>
-                <variablelist>r1 (symbolic name sp) is the control stack pointer, 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 allocbase) are used to do per-thread memory allocation</variablelist>
-                <variablelist>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.</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 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.</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 temp stack.</para>
+		</listitem>
+		<listitem>
+		  <para>r13 is used to hold the TCR on PPC32 sytems; it's not used on PPC64.</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="Tagging-scheme">
-        <para>Tagging schemeOpenMCL 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 = 3 for 32-bit OpenMCL and N = 4
-for 64-bit OpenMCL), this way of representing fixnums with the low
-M bits forced to 0 works as long as M <= 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 = 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>
-        <listitem mark="bullet">
-          <variablelist>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 CARand CDR in memory were chosen to allow smaller, cheaper addressing modesto 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 inmemory.  It doesn't matter, but doing it the way that the host systemdid made boostrapping to a new target system a little easier.)</variablelist>
-          <variablelist>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 truthvalue and probably a few other things.)  Its role as a LIST is probablymuch 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 LISTPimplicitly 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 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 thereforetrue of any node whose low 2 (or 3) bits contain the appropriate tagvalue (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 architectural restrictions dictate the set of tagsthat can be used to access fixed 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 cellsCDR and CAR would be.  NIL's pname is set to NIL (SYMBOL-NAMEchecks for this 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, the 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 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.</variablelist>
-          <variablelist>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 thetreatment of "memory-allocated non-CONS objects" isn't entirely uniformaccross all OpenMCL 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 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.)</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 = 3 for 32-bit
+	OpenMCL and N = 4 for 64-bit OpenMCL), this way of
+	representing fixnums with the low M bits forced to 0 works as
+	long as M &lt;= 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 = 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="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. ("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 &ndash;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 (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>
+      <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="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="arabic">
-          <variablelist>decrementing the "high" pointer by (- X Y)</variablelist>
-          <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</variablelist>
-        </varlistentry>
-        <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>
+	<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)
@@ -10251,9 +14594,10 @@
   (RLWINM ALLOCPTR ALLOCPTR 0 0 28)     ; clear tag bits
 </programlisting>
-        <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>
+        <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
@@ -10267,51 +14611,61 @@
   (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="Allocation-of-reserved-heap-segments">
-        <para>Allocation of reserved heap segmentsAfter 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>
+	<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="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 failure that
 wasn't preceeded by several minutes of excessive paging activity.  The
@@ -10323,408 +14677,537 @@
 
     <sect1 id="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</para>
-      <varlistentry numeration="arabic">
-        <variablelist>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.)</variablelist>
-        <variablelist>the relocation table, which contains a native word for every 32 or 64doublenodes in the dynamic heap, plus an extra word used to 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 are</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="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 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>
-        <varlistentry numeration="arabic">
-          <variablelist>If the object is already marked, do nothing.</variablelist>
-          <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 mark 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:</para>
-        <varlistentry numeration="arabic">
-          <variablelist>To support a feature called <emphasis>GCTWA
-              <tip>
-<para>I believe that theacronym comes from MACLISP, where it stood for "Garbage 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 they're somehowdistinguishable from newly created symbols (by virtue of their havingfunction bindings, value bindings, plists, or other attributes.)</variablelist>
-          <variablelist>Pools have their first element set to NIL before any 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 ifthere 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 which
-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="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 preced
-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 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>
+	<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="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 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>
+	<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="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 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>
+	<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="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 exploit
-the following assumptions:</para>
-      <listitem mark="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 result 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) 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).<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 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>
-      <listitem mark="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 middle of theglobal markbits table; preceding entries in this table are used tonote doubleword addresses in older generations that (may) containintergenerational references;</variablelist>
-        <variablelist>some steps (notably GCTWA and the handling of weak objects) arenot performed;</variablelist>
-        <variablelist>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.</variablelist>
-      
-      </listitem>
-      <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>
+      </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="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 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>
+      <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="Heap-images">
-      <para>Heap images
-Needs complete rewrite.</para>
-    </sect1>
-
-    <sect1 id="Operating-system-dependencies">
-      <para>Operating system dependencies</para>
-    </sect1>
+
 
     <sect1 id="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="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 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>
+	<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="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.</variablelist>
-          </indexterm>
-        </term>
+      <sect2>
+	<title>Recommended Reading</title>
+
+	<variablelist>
+	  <varlistentry>
+	    <term>
+	      <ulink url="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="http://developer.apple.com/documentation/Cocoa/Reference/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="Modifying-OpenMCL">
-    <para>Modifying OpenMCL</para>
+    <title>Modifying OpenMCL</title>
 
     <sect1 id="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="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="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!
@@ -10736,5 +15219,5 @@
 ? (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
@@ -10750,6 +15233,6 @@
       <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 ?
@@ -10762,16 +15245,18 @@
 ? 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 see 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
@@ -10779,15 +15264,17 @@
 (?)  Show this help
 </programlisting>
-      <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 ((> 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
@@ -10795,5 +15282,5 @@
 ? (classify2 0)
 Lisp Breakpoint
- While executing: #<Function CLASSIFY2 #x08476cfe>
+ While executing: #&lt;Function CLASSIFY2 #x08476cfe>
 ? for help
 [12345] OpenMCL kernel debugger: ?
@@ -10817,16 +15304,16 @@
       <programlisting>rnil = 0x01836015
 nargs = 0
-r16 (fn) = #<Function CLASSIFY2 #x30379386>
+r16 (fn) = #&lt;Function CLASSIFY2 #x30379386>
 r23 (arg_z) = 0
 r22 (arg_y) = 0
 r21 (arg_x) = 0
-r20 (temp0) = #<26-element vector subtag = 2F @#x303793ee>
+r20 (temp0) = #&lt;26-element vector subtag = 2F @#x303793ee>
 r19 (temp1/next_method_context) = 6393788
-r18 (temp2/nfn) = #<Function CLASSIFY2 #x30379386>
+r18 (temp2/nfn) = #&lt;Function CLASSIFY2 #x30379386>
 r17 (temp3/fname) = CLASSIFY2
 r31 (save0) = 0
 r30 (save1) = *TERMINAL-IO*
 r29 (save2) = 0
-r28 (save3) = (#<RESTART @#x01867f2e> #<RESTART @#x01867f56>)
+r28 (save3) = (#&lt;RESTART @#x01867f2e> #&lt;RESTART @#x01867f56>)
 r27 (save4) = ()
 r26 (save5) = ()
@@ -10847,44 +15334,47 @@
 
     <sect1 id="Using-AltiVec-in-OpenMCL-LAP-functions">
-      <para>Using AltiVec in OpenMCL LAP functions</para>
+      <title>Using AltiVec in OpenMCL LAP functions</title>
 
       <sect2 id="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 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>
+	<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="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 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>
+	<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
@@ -10932,440 +15422,262 @@
 
     <sect1 id="Development-Mode-Dictionary">
-      <para>Development-Mode Dictionary</para>
-
-      <sect2 id="iWARN-IF-REDEFINE-KERNEL-">
-        <para>*WARN-IF-REDEFINE-KERNEL*</para>
-        <informalfigure>*warn-if-redefine-kernel</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>*WARN-IF-REDEFINE-KERNEL* &mdash;</para>
-        <para>Variable</para>
-        <bridgehead renderas="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="SET-DEVELOPMENT-ENVIRONMENT">
-        <para>SET-DEVELOPMENT-ENVIRONMENT</para>
-        <informalfigure>set-development-environment</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SET-DEVELOPMENT-ENVIRONMENT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-set-development-environment
-	  &amp;optional
-	  unmark-builtin-functions
-</programlisting>
-        <bridgehead renderas="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="SET-USER-ENVIRONMENT">
-        <para>SET-USER-ENVIRONMENT</para>
-        <informalfigure>set-user-environment</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>SET-USER-ENVIRONMENT &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-set-user-environment
-	  &amp;optional mark-builtin-functions
-</programlisting>
-        <bridgehead renderas="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="iALTIVEC-AVAILABLE-">
-        <para>*ALTIVEC-AVAILABLE*</para>
-        <informalfigure>*altivec-available*</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>*ALTIVEC-AVAILABLE* &mdash;</para>
-        <para>Variable</para>
-        <bridgehead renderas="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="ALTIVEC-AVAILABLE-P">
-        <para>ALTIVEC-AVAILABLE-P</para>
-        <informalfigure>altivec-available-p</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>ALTIVEC-AVAILABLE-P &mdash;</para>
-        <para>Function</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-altivec-available-p
-</programlisting>
-        <bridgehead renderas="sect3">Description</bridgehead>
-        <para>Returns non-NIL if AltiVec is available.</para>
-      </sect2>
-
-      <sect2 id="iALTIVEC-LAPMACROS-MAINTAIN-VRSAVE-P-">
-        <para>*ALTIVEC-LAPMACROS-MAINTAIN-VRSAVE-P*</para>
-        <informalfigure>*altivec-lapmacros-maintain-vrsave-p*</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>*ALTIVEC-LAPMACROS-MAINTAIN-VRSAVE-P* &mdash;</para>
-        <para>Variable</para>
-        <bridgehead renderas="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="WITH-ALTIVEC-REGISTERS">
-        <para>WITH-ALTIVEC-REGISTERS</para>
-        <informalfigure>with-altivec-registers</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>WITH-ALTIVEC-REGISTERS &mdash;</para>
-        <para>LAP Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-with-altivec-registers
-	  reglist &amp;body body
-</programlisting>
-        <bridgehead renderas="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.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="WITH-VECTOR-BUFFER">
-        <para>WITH-VECTOR-BUFFER</para>
-        <informalfigure>with-vector-buffer</informalfigure>
-        <bridgehead renderas="sect3">Name</bridgehead>
-        <para>WITH-VECTOR-BUFFER &mdash;</para>
-        <para>LAP Macro</para>
-        <bridgehead renderas="sect3">Synopsis</bridgehead>
-        <programlisting>
-with-vector-buffer base n &amp;body body
-</programlisting>
-        <bridgehead renderas="sect3">Arguments and Values</bridgehead>
-        <term><indexterm>base
-            <variablelist>Any available general-purpose register.</variablelist>
-          </indexterm><indexterm>n
-            <variablelist>An integer between 1 and 254, inclusive. (Shouldtypically be much, much closer to 1.) Specifies the size ofthe buffer, in 16-byte units.</variablelist>
-          </indexterm><indexterm>body
-            <variablelist>A sequence of PPC LAP instructions.</variablelist>
-          </indexterm>
-        </term>
-        <bridgehead renderas="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="v_warn-if-redefine-kernel">
+	<indexterm zone="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="f_set-development-environment">
+	<indexterm zone="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="f_set-user-environment">
+	<indexterm zone="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="v_altivec-available">
+	<indexterm zone="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="f_altivec-available-p">
+	<indexterm zone="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="v_altivec-lapmacros-maintain-vrsave-p">
+	<indexterm zone="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="lapm_with-altivec-registers">
+	<indexterm zone="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="lapm_with-vector-buffer">
+	<indexterm zone="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></secondaryie>
-  <secondaryie>
-    <indexdiv>*alternate-line-terminator*, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>*altivec-available*, see </indexdiv></secondaryie>
-  <secondaryie>
-    <indexdiv>*altivec-lapmacros-maintain-vrsave-p*, see </indexdiv></secondaryie>
-  <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></tgroup>
-<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></tgroup>
-<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></secondaryie>
-  <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></tgroup>
-<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>
-
