<?xml version="1.0" encoding="UTF-8"?>

<chapter id="ext-p-indep"><title>Platform Independent Extensions</title>

<section id="custom-init-fini"><title>Customizing &clisp; Process
  Initialization and Termination</title>

<section id="cradle-grave"><title>Cradle to Grave</title>
<subtitle>What is done when</subtitle>
<procedure><step><title>Initialization</title>
 <substeps><step><simpara>Parse command line arguments until the first
    positional argument (see &script-k;).</simpara></step>
  <step><simpara>Load the &mem-image;.</simpara></step>
  <step><simpara>Install internal signal handlers.</simpara></step>
  <step><simpara>Initialize time variables.</simpara></step>
  <step><simpara>Initialize <link linkend="enc-dflt">locale-dependent
     encodings</link>.</simpara></step>
  <step><simpara>Initialize stream variables.</simpara></step>
  <step><simpara>Initialize pathname variables.</simpara></step>
  <step><simpara>Initialize &ffi-pac;.</simpara></step>
  <step><simpara><link linkend="modinit">Initialize
     modules</link>.</simpara></step>
  <step><simpara>Run all functions in &init-hooks;.</simpara></step>
  <step><simpara>Say <quote>hi</quote>, unless suppressed by &opt-q;.
  </simpara></step><step><simpara>Load &RC-file;, unless suppressed by
    &opt-norc;.</simpara></step></substeps></step>
<step><title>The actual work</title><para>Handle command line options: file
  <olink targetdoc="man" targetptr="opt-init">loading</olink> and/or
  <olink targetdoc="man" targetptr="opt-compile">compilation</olink>,
  <olink targetdoc="man" targetptr="opt-exec-expr">form evaluation</olink>,
  &script; execution, &repl;.</para></step>
<step><title>Finalization (executed even on abnormal exit due
  to <function role="unix">kill</function>)</title>
 <substeps><step><simpara>Unwind the &STACK;, executing cleanup forms in
    &unwind-protect;.</simpara></step>
  <step><simpara>Run all functions in &fini-hooks;.</simpara></step>
  <step><simpara>Call &fresh-line; on the standard streams.</simpara></step>
  <step><simpara>Say <quote>bye</quote> unless suppressed by &opt-q;.
  </simpara></step>
  <step><simpara>Wait for a keypress if requested by
    <option><olink targetdoc="man" targetptr="opt-wait">-w</olink></option>.
  </simpara></step>
  <step><simpara>Close all open &file-stream-t;s.</simpara></step>
  <step><simpara><link linkend="modfini">Finalize
     modules</link>.</simpara></step>
  <step><simpara>Close all open DLLs.</simpara></step>
</substeps></step></procedure></section>

<section id="init-hooks"><title>Customizing Initialization</title>
<para>&init-hooks; is run like this:<programlisting language="lisp">
(&ignore-errors; (&mapc; #'&funcall; &init-hooks;))
</programlisting></para>
<section id="init-hooks-function"><title>The difference between
  &init-hooks; and &init-function;</title>
<para><itemizedlist><listitem><simpara>&init-hooks; are
    <emphasis>always</emphasis> run regardless of the command line
    options before even the banner is printed.</simpara></listitem>
  <listitem><simpara>The &init-function; is run <emphasis>only</emphasis>
    if the &repl; is ever entered and just before the
    first <link linkend="prompt">prompt</link> is printed.
</simpara></listitem></itemizedlist></para></section>
</section>

<section id="fini-hooks"><title>Customizing Termination</title>
<para>&fini-hooks; is run like this:<programlisting language="lisp">
(&mapc; #'&funcall; &fini-hooks;)
</programlisting></para></section>

</section>

<section id="image"><title>Saving an Image</title>

<para>The function <code>(&savemem; &optional-amp;
  (&filename-r; "lispinit.mem") &key-amp; :KEEP-GLOBAL-HANDLERS :QUIET
  :INIT-FUNCTION :LOCKED-PACKAGES :START-PACKAGE :EXECUTABLE :NORC
  :SCRIPT :DOCUMENTATION :VERBOSE)</code>
 saves the running &clisp;'s memory to the file &filename-r;;
 extension &mem-file; is recommended (when &filename-r; does not have an
 extension, &mem-file; extension is automatically added unless the file
 being created is an executable).
<variablelist>
 <varlistentry><term><constant>:QUIET</constant></term>
  <listitem><simpara>If this argument is not &nil;, the startup banner
    and the good-bye message will be suppressed, as if by &opt-q;.</simpara>
   <simpara>This is &not-e; recommended for interactive application delivery,
    please <emphasis>append</emphasis> your banner to ours (using
    &init-function;) instead of <emphasis>replacing</emphasis> it.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&verbose-k;</term>
  <listitem><simpara>Print a message after writing the file.
    This argument defaults to &savemem-verbose;; initial value is &t;.
 </simpara></listitem></varlistentry>
 <varlistentry><term><constant>:NORC</constant></term>
  <listitem><simpara>If this argument is not &nil;, the &RC-file;
    loading will be suppressed, as if by &opt-norc;.
 </simpara></listitem></varlistentry>
 <varlistentry id="init-func"><term><constant>:INIT-FUNCTION</constant></term>
  <listitem><simpara>This argument specifies a function that will be
   executed at startup of the saved image, before entering the standard &repl;
   (but after all other initialization, see <xref linkend="cradle-grave"/>);
   thus, if you want to avoid the &repl;, you have to call &exit; at the
   end of the init function yourself
   (this does not prevent &fini-hooks; from being run).</simpara>
   <simpara>See <olink targetdoc="man" targetptr="opt-exec-file">the
     manual</olink> for passing command line arguments to this function.
   </simpara><simpara>See also &init-hooks; and &fini-hooks;.</simpara>
 </listitem></varlistentry>
 <varlistentry id="image-script"><term>&script-k;</term>
  <listitem><para>This options determines the handling of positional
    arguments when the image is invoked.<itemizedlist>
     <listitem><simpara>If it is &t;, then the first positional argument
       is the script name and the rest is placed into &args;, as described
       in <xref linkend="quickstart-unix"/>.</simpara></listitem>
     <listitem><simpara>It it is &nil;, then all positional arguments
       are placed into &args; to be handled by the &init-function;.
     </simpara></listitem></itemizedlist>
    This option defaults to &t; when &init-function; is &nil; and to
    &nil; when &init-function; is non-&nil;.
 </para></listitem></varlistentry>
 <varlistentry id="image-doc"><term>&documentation-k;</term>
  <listitem><simpara>The description of what this image does, printed
    by the <option><olink targetdoc="man" targetptr="opt-help-image"
                          >-help-image</olink></option> olption.</simpara>
   <simpara>Defaults to <code>(&documentation; &init-function;
     '&function-doc;)</code></simpara></listitem></varlistentry>
 <varlistentry><term><constant>:LOCKED-PACKAGES</constant></term>
  <listitem><simpara>This argument specifies the packages to lock before
   saving the image; this is convenient for application delivery, when
   you do not want your users to mess up your product.
   This argument defaults to &sys-pack-list;.
 </simpara></listitem></varlistentry>
 <varlistentry><term><constant>:START-PACKAGE</constant></term>
  <listitem><simpara>This argument specifies the starting value of
   &package-var; in the image being saved, and defaults to the current
   value of &package-var;.</simpara></listitem></varlistentry>
 <varlistentry><term><constant>:KEEP-GLOBAL-HANDLERS</constant></term>
  <listitem><para>When non-&nil;, the currently established global
    handlers (either with &set-global-handler; or with &opt-on-error;)
    are inherited by the image.  Defaults to &nil;, so that
    <screen>&sh-prompt; &clisp-cmd; &opt-i; myfile &opt-x; '(&savemem;)'</screen>
    will produce an image without any global handlers inherited
    from the batch mode of the above command.</para></listitem></varlistentry>
 <varlistentry id="image-exec"><term><constant>:EXECUTABLE</constant></term>
  <listitem><simpara>When non-&nil;, the saved file will be a
    standalone executable.
    In this case, the &mem-file; extension is not added.
    On &win32; and &cygwin; the extension <filename>#P".exe"</filename>
    is added instead.</simpara>
   <para>Additionally, if this argument is &zero;, the standard
    &clisp; command line options will &not-e; be processed by the
    executable but will be placed into &args; instead.
    This is convenient for application delivery, so that your
    &clisp;-based application can accept, e.g., &opt-x;.
    To override this feature of the image, you have to prefix the
    options with <literal>"--clisp"</literal>, e.g.,
    use <option>--clisp-x</option> instead of &opt-x;.
    This, given such a &clisp;-based application, you can get to an
    ordinary &clisp; &repl; by doing <screen>
&sh-prompt; application --clisp-x '(&savemem; "myclisp" :executable t :init-function nil)'
&sh-prompt; ./myclisp
[1]&gt; (<link linkend="factorial">!</link> 20)
2432902008176640000</screen>
    These instructions are also printed by
    <option>--clisp--help</option>.</para>
   <simpara>Of course, this feature opens a <emphasis>security hole</emphasis>
    if the application is running <function role="unix">setuid</function> root,
    therefore &clisp; resets the effective group and user IDs to the real
    ones if it sees a <literal>"--clisp-*"</literal> option.
</simpara></listitem></varlistentry></variablelist>
You can use this memory image with the &opt-M; option.
On &unix; systems, you may compress it with &gnu; &gzip; to save disk
space.</para>

<section id="image-portability"><title>Image Portability</title>
 <para>Memory images are &not-e; portable across different platforms
  (in contrast with platform-independent &fasl-file; files).
  They are &not-e; even portable across &linkset;s: image saved using
  the &full; &linkset; cannot be used with the &base; &rt;:<screen>
&sh-prompt; &clisp-cmd; &opt-K; full &opt-x; '(&savemem;)'
&sh-prompt; &clisp-cmd; &opt-K; base &opt-M; lispinit.mem
base/lisp.run: initialization file `lispinit.mem' was not created by this version of CLISP runtime</screen>
See also <ulink role="sfmail" url="BF6EFF38DF3FA647BBD932720D8BED650BAA11%40parmbx02.ilog.biz"/>/<ulink role="gmane" url="devel/17757"/>.</para></section>

</section>

<section id="quit"><title>Quitting &clisp;</title>

<para>The functions <simplelist>
  <member><code>(&exit; &optional-amp; &status-r;)</code></member>
  <member><code>(EXT:QUIT &optional-amp; &status-r;)</code></member>
  <member><code>(EXT:BYE &optional-amp; &status-r;)</code></member></simplelist>
 - all synonymous - terminate &clisp;.  If &status-r; is non-&nil;,
 &clisp; aborts with the supplied numeric error &status-r;, i.e.,
 the OS environment is informed that the &clisp; session did not
 succeed.</para>

<para><link linkend="fin-delim">Final delimiter</link>s also terminate
 &clisp;.</para>

</section>

<section id="i18n"><title>Internationalization of &clisp;</title>

<variablelist><title>Glossary</title>
 <varlistentry><term>Internationalization (<quote>i18n</quote>)</term>
  <listitem><simpara>preparing a program so that it can use multiple
    national languages and national cultural conventions without requiring
    further source code changes.</simpara></listitem></varlistentry>
 <varlistentry><term>Localization (<quote>l10n</quote>)</term>
  <listitem><simpara>providing the data - mostly textual translations -
    necessary for an internationalized program to work in a particular
    language and with particular cultural conventions.
</simpara></listitem></varlistentry></variablelist>

<para>&clisp; is internationalized, and is localized for the languages
English, German, French, Spanish, Dutch, Russian, and Danish.
&clisp; also supports internationalized Lisp programs, through
&ggettext;, see <xref linkend="i18n-mod"/>.</para>

<section id="language"><title>The Language</title>

<warning><para>The facilities described in this section will
  work only for the languages for which &clisp; itself is already
  localized.</para></warning>

<para>The language &clisp; uses to communicate with the user can be one of
<simplelist columns="1">
 <member><constant>ENGLISH</constant></member>
 <member><constant>DEUTSCH</constant> (i.e., German)</member>
 <member><constant>FRAN&Ccedil;AIS</constant> (i.e., French)</member>
 <member><constant>ESPA&Ntilde;OL</constant> (i.e., Spanish)</member>
 <member><constant>NEDERLANDS</constant> (i.e., Dutch)</member>
 <member><constant>&Rcy;&Ucy;&Scy;&Scy;&Kcy;&Icy;&Jcy;</constant>
  (i.e. Russian)</member>
 <member><constant>DANSK</constant> (i.e., Danish)</member>
</simplelist></para>

<para>This is controlled by the &symbol-macro;
 <firstterm>&curr-lang;<indexterm id="curr-lang" significance="preferred">
   <primary><varname>*CURRENT-LANGUAGE*</varname>
 </primary></indexterm></firstterm>,
 which can be set at run time as well as using the &opt-L; command line option.
 If you wish to change the
 <olink targetdoc="man" targetptr="opt-locale">locale directory</olink>
 at run time too, you can do that by setting &curr-lang; to a &cons-t;
 cell, whose &car; is the language (a &symbol-t;, one of the above),
 and whose &cdr; is the new locale directory.</para>

<para>More languages can be defined through the macro
 <firstterm>&deflang;<indexterm id="deflang" significance="preferred">
   <primary><function>DEFLANGUAGE</function></primary></indexterm></firstterm>:
 <code>(&deflang; &lang-r;)</code>.
 For such an additional language to take effect, you must install the
 corresponding message catalog, or translate the messages yourself,
 using &ggettext; and &emacs; (or &xemacs;)
 <ulink url="google">po-mode</ulink>.</para>

<para>This works only for strings.  For arbitrary language-dependent
 Lisp objects, you define one through the macro
 <firstterm>&def-i-l;<indexterm id="def-i-l" significance="preferred">
   <primary><function>DEFINTERNATIONAL</function>
 </primary></indexterm></firstterm>:
 <code>(&def-i-l; &symbol-r; &optional-amp;
 (<replaceable>default-language</replaceable> &t;))</code> and add
 language-dependent values through the macro
 <firstterm>&defloc;<indexterm id="defloc" significance="preferred">
   <primary><function>DEFLOCALIZED</function></primary></indexterm></firstterm>:
 <code>(&defloc; &symbol-r; &lang-r;
  <replaceable>value-form</replaceable>)</code>
 (One such form for each language.  Languages without an assigned
 value will be treated like the default-language.)
 You can then access the localized value by calling
 <firstterm>&localized;<indexterm id="localized" significance="preferred">
   <primary><function>LOCALIZED</function></primary></indexterm></firstterm>:
 <code>(&localized; &symbol-r; &optional-amp; &lang-r;)</code></para>

</section>

</section>

<section id="encoding"><title>Encodings</title>

<section id="encodings-intro"><title>Introduction</title>

<para>An <quote>encoding</quote> describes the correspondence
 between &character-t;s and raw bytes during input/output via
 &stream-t;s with &stream-element-type; &character-t;.</para>

<para>An &encoding; is an object composed of the following facets:
<variablelist>
 <varlistentry><term><link linkend="charset">character set</link></term>
  <listitem><simpara>This denotes both the set of &character-t;s that
    can be represented and passed through the I/O channel, and the way
    these characters translate into raw bytes, i.e., the map between
    sequences of &character-t; and &ubyte-8; in the form of &string-t;s
    and &ubyte-vec; as well as character and byte &stream-t;s.
    In this context, for example, &utf-8; and &ucs-4;
    are considered different, although they can represent the same set
    of characters.</simpara></listitem></varlistentry>
 <varlistentry><term>&line-term; mode</term>
  <listitem><simpara>This denotes the way newline characters are
    represented.</simpara></listitem></varlistentry>
</variablelist></para>

<para>&encoding;s are also &type-glo;s.  As such, they represent the set of
 characters encodable in the character set.  In this context, the way
 characters are translated into raw bytes is ignored, and the line
 terminator mode is ignored as well.  &typep; and &subtypep; can be used
 on encodings:<programlisting language="lisp">
(&subtypep; &utf-8; &utf-16;)
<computeroutput>&t;</computeroutput> ;
<computeroutput>&t;</computeroutput>
(&subtypep; &utf-16; &utf-8;)
<computeroutput>&t;</computeroutput> ;
<computeroutput>&t;</computeroutput>
(&subtypep; CHARSET:ASCII CHARSET:ISO-8859-1)
<computeroutput>&t;</computeroutput> ;
<computeroutput>&t;</computeroutput>
(&subtypep; CHARSET:ISO-8859-1 CHARSET:ASCII)
<computeroutput>&nil;</computeroutput> ;
<computeroutput>&t;</computeroutput>
</programlisting></para>

<formalpara id="enc1-1"><title><quote>1:1</quote> encodings</title>
<para>Encodings which define a bijection between character and byte
 sequences are called &enc1-1;s. &iso-8859-1; is an example of such an
 encoding: any byte sequence corresponds to some character sequence and
 vice versa.  &ascii;, however, is &not-e; a &enc1-1;: there are no
 characters for bytes in the range [128;255]. &utf-8; is &not-e; a
 &enc1-1; either: some byte sequences do not correspond to any character
 sequence.</para></formalpara>

</section>

<section id="charset"><title>Character Sets</title>

<variablelist>
<!-- #ifndef ENABLE_UNICODE -->
<varlistentry><term>&non-unicode-only;</term>
<listitem><simpara>Only one character set is understood: the platform's
 native (8-bit) character set.  See <xref linkend="characters"/>.
</simpara></listitem></varlistentry>
<!-- #else -->
<varlistentry id="charset-symbols"><term>&unicode-only;</term>
<listitem><para>The following character sets are supported, as values
 of the corresponding (constant) symbol in the &charset-pac; package:
<orderedlist id="charset-symbol-list">
 <title>Symbols in package &charset-pac;</title>
 <listitem id="charset-UCS-2"><simpara><constant>UCS-2</constant>
   &equiv; <constant>UNICODE-16</constant>
   &equiv; <constant>UNICODE-16-BIG-ENDIAN</constant>,
   the 16-bit basic multilingual plane of the &unicode; character set.
   Every character is represented as two bytes.</simpara></listitem>
 <listitem id="charset-UNICODE-16-LITTLE-ENDIAN"><simpara><constant>UNICODE-16-LITTLE-ENDIAN</constant>
    </simpara></listitem>
 <listitem id="charset-UCS-4"><simpara><constant>UCS-4</constant>
   &equiv; <constant>UNICODE-32</constant>
   &equiv; <constant>UNICODE-32-BIG-ENDIAN</constant>,
   the 21-bit &unicode; character set. Every character is represented as
   four bytes. This encoding is used by &clisp; internally.</simpara></listitem>
 <listitem id="charset-UNICODE-32-LITTLE-ENDIAN">
  <simpara><constant>UNICODE-32-LITTLE-ENDIAN</constant></simpara></listitem>
 <listitem id="charset-UTF-8"><simpara><constant>UTF-8</constant>,
   the 21-bit &unicode; character set.
   Every character is represented as one to four bytes.
   &ascii; characters represent themselves and need one byte per character.
   Most Latin/Greek/Cyrillic/Hebrew characters need two bytes per
   character. Most other characters need three bytes per character,
   and the rarely used remaining characters need four bytes per
   character. This is therefore, in general, the most space-efficient
   encoding of all of Unicode.</simpara></listitem>
<!-- #ifdef GNU_LIBICONV -->
 <listitem id="charset-UTF-16"><simpara><constant>UTF-16</constant>,
   the 21-bit &unicode; character set. Every character in the 16-bit
   basic multilingual plane is represented as two bytes, and the
   rarely used remaining characters need four bytes per character.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-UTF-7"><simpara><constant>UTF-7</constant>,
   the 21-bit &unicode; character set. This is a stateful 7-bit encoding.
   Not all &ascii; characters represent themselves.
   &charset-glibc-libiconv;</simpara></listitem>
<!-- #endif /* GNU_LIBICONV */ -->
 <listitem id="charset-JAVA"><simpara><constant>JAVA</constant>,
   the 21-bit &unicode; character set.
   &ascii; characters represent themselves and need one byte per character.
   All other characters of the basic multilingual plane are represented
   by <literal>\u<replaceable>nnnn</replaceable></literal> sequences
   (<replaceable>nnnn</replaceable> a hexadecimal number)
   and need 6 bytes per character. The remaining characters are represented
   by <literal>\u<replaceable>xxxx</replaceable>\u<replaceable>yyyy</replaceable></literal>
   and need 12 bytes per character. While this encoding is very comfortable
   for editing Unicode files using only &ascii;-aware tools and editors, it
   cannot faithfully represent all &unicode; text. Only text which
   does not contain <literal>\u</literal> (backslash followed by
   lowercase Latin u) can be faithfully represented by this encoding.
 </simpara></listitem>
 <listitem id="charset-ASCII"><simpara><constant>ASCII</constant>,
   the well-known US-centric 7-bit character set (American Standard
   Code for Information Interchange - &ascii;).</simpara></listitem>
 <listitem id="charset-ISO-8859-1"><simpara><constant>ISO-8859-1</constant>,
   &ascii-iso-ext; Afrikaans, Albanian, Basque, Breton, Catalan,
   Cornish, Danish, Dutch, English, F&aelig;roese, Finnish, French,
   Frisian, Galician, German, Greenlandic, Icelandic, Irish, Italian,
   Latin, Luxemburgish, Norwegian, Portuguese, R&aelig;to-Romanic,
   Scottish, Spanish, and Swedish languages.</simpara>
  <para>This encoding has the nice property that<programlisting language="lisp">
(&loop; :for i :from 0 :to &char-code-limit; :for c = (&code-char; i)
  :always (&or-m; (&not-f; (&typep; c CHARSET:ISO-8859-1))
              (&equalp; (&convert-string-to-bytes; (&string; c) CHARSET:ISO-8859-1)
                      (&vector; i))))
<computeroutput>T</computeroutput></programlisting>
   i.e., it is compatible with &clisp; &code-char;/&char-code;
   in its own domain.</para></listitem>
 <listitem id="charset-ISO-8859-2"><simpara><constant>ISO-8859-2</constant>,
   &ascii-iso-ext; Croatian, Czech, German, Hungarian, Polish,
   Slovak, Slovenian, and Sorbian languages. </simpara></listitem>
 <listitem id="charset-ISO-8859-3"><simpara><constant>ISO-8859-3</constant>,
   &ascii-iso-ext; Esperanto and Maltese languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-4"><simpara><constant>ISO-8859-4</constant>,
   &ascii-iso-ext; Estonian, Latvian, Lithuanian and Sami (Lappish)
   languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-5"><simpara><constant>ISO-8859-5</constant>,
   &ascii-iso-ext; Bulgarian, Byelorussian, Macedonian, Russian,
   Serbian, and Ukrainian languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-6"><simpara><constant>ISO-8859-6</constant>,
   suitable for the Arabic language.</simpara></listitem>
 <listitem id="charset-ISO-8859-7"><simpara><constant>ISO-8859-7</constant>,
   &ascii-iso-ext; Greek language.</simpara></listitem>
 <listitem id="charset-ISO-8859-8"><simpara><constant>ISO-8859-8</constant>,
   &ascii-iso-ext; Hebrew language (without punctuation).</simpara></listitem>
 <listitem id="charset-ISO-8859-9"><simpara><constant>ISO-8859-9</constant>,
   &ascii-iso-ext; Turkish language.</simpara></listitem>
 <listitem id="charset-ISO-8859-10"><simpara><constant>ISO-8859-10</constant>,
   &ascii-iso-ext; Estonian, Icelandic, Inuit (Greenlandic), Latvian,
   Lithuanian, and Sami (Lappish) languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-13"><simpara><constant>ISO-8859-13</constant>,
   &ascii-iso-ext; Estonian, Latvian, Lithuanian, Polish and Sami
   (Lappish) languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-14"><simpara><constant>ISO-8859-14</constant>,
   &ascii-iso-ext; Irish G&aelig;lic, Manx G&aelig;lic, Scottish
   G&aelig;lic, and Welsh languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-15"><simpara><constant>ISO-8859-15</constant>,
   &ascii-iso-ext; ISO-8859-1 languages, with improvements for
   French, Finnish and the Euro.</simpara></listitem>
 <listitem id="charset-ISO-8859-16"><simpara><constant>ISO-8859-16</constant>
   &ascii-iso-ext; Rumanian language.</simpara></listitem>
 <listitem id="charset-KOI8-R"><simpara><constant>KOI8-R</constant>,
   &ascii-iso-ext; Russian language (very popular, especially on the
   internet).</simpara></listitem>
 <listitem id="charset-KOI8-U"><simpara><constant>KOI8-U</constant>,
   &ascii-iso-ext; Ukrainian language (very popular, especially on the
   internet).</simpara></listitem>
<!-- #ifdef GNU_LIBICONV -->
 <listitem id="charset-KOI8-RU"><simpara><constant>KOI8-RU</constant>,
   &ascii-iso-ext; Russian language. &charset-libiconv;</simpara></listitem>
<!-- #endif /* GNU_LIBICONV */ -->
 <listitem><simpara><constant>JIS_X0201</constant>,
   a character set for the Japanese language.</simpara></listitem>
 <listitem id="charset-MAC-ARABIC"><simpara><constant>MAC-ARABIC</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-CENTRAL-EUROPE"><simpara><constant>MAC-CENTRAL-EUROPE</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-CROATIAN"><simpara><constant>MAC-CROATIAN</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-CYRILLIC"><simpara><constant>MAC-CYRILLIC</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-DINGBAT"><simpara><constant>MAC-DINGBAT</constant>,
   a platform specific character set.</simpara></listitem>
 <listitem id="charset-MAC-GREEK"><simpara><constant>MAC-GREEK</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-HEBREW"><simpara><constant>MAC-HEBREW</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-ICELAND"><simpara><constant>MAC-ICELAND</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-ROMAN"><simpara><constant>MAC-ROMAN</constant>
   &equiv; <constant>MACINTOSH</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-ROMANIA"><simpara><constant>MAC-ROMANIA</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-SYMBOL"><simpara><constant>MAC-SYMBOL</constant>,
   a platform specific character set.</simpara></listitem>
 <listitem id="charset-MAC-THAI"><simpara><constant>MAC-THAI</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-TURKISH"><simpara><constant>MAC-TURKISH</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-UKRAINE"><simpara><constant>MAC-UKRAINE</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-CP437"><simpara><constant>CP437</constant>, a DOS oldie,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-CP437-IBM"><simpara><constant>CP437-IBM</constant>,
   an IBM variant of <constant>CP437</constant>.</simpara></listitem>
 <listitem id="charset-CP737"><simpara><constant>CP737</constant>, a DOS oldie,
   &ascii-pl-ext;, &good-for; the Greek language.</simpara></listitem>
 <listitem id="charset-CP775"><simpara><constant>CP775</constant>, a DOS oldie,
   &ascii-pl-ext;, &good-for; some Baltic languages.</simpara></listitem>
 <listitem id="charset-CP850"><simpara><constant>CP850</constant>, a DOS oldie,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-CP852"><simpara><constant>CP852</constant>, a DOS oldie,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-CP852-IBM"><simpara><constant>CP852-IBM</constant>,
   an IBM variant of <constant>CP852</constant>.</simpara></listitem>
 <listitem id="charset-CP855"><simpara><constant>CP855</constant>, a DOS oldie,
   &ascii-pl-ext;, &good-for; the Russian language.</simpara></listitem>
 <listitem id="charset-CP857"><simpara><constant>CP857</constant>, a DOS oldie,
   &ascii-pl-ext;, &good-for; the Turkish language.</simpara></listitem>
 <listitem id="charset-CP860"><simpara><constant>CP860</constant>, a DOS oldie,
   &ascii-pl-ext;, &good-for; the Portuguese language.</simpara></listitem>
 <listitem id="charset-CP860-IBM"><simpara><constant>CP860-IBM</constant>,
   an IBM variant of <constant>CP860</constant>.</simpara></listitem>
 <listitem id="charset-CP861"><simpara><constant>CP861</constant>, a DOS oldie,
   &ascii-pl-ext;, &good-for; the Icelandic language.</simpara></listitem>
 <listitem id="charset-CP861-IBM"><simpara><constant>CP861-IBM</constant>,
   an IBM variant of <constant>CP861</constant>.</simpara></listitem>
 <listitem id="charset-CP862"><simpara><constant>CP862</constant>, a DOS oldie,
   &ascii-pl-ext;, &good-for; the Hebrew language.</simpara></listitem>
 <listitem id="charset-CP862-IBM"><simpara><constant>CP862-IBM</constant>,
   an IBM variant of <constant>CP862</constant>.</simpara></listitem>
 <listitem id="charset-CP863"><simpara><constant>CP863</constant>, a DOS oldie,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-CP863-IBM"><simpara><constant>CP863-IBM</constant>,
   an IBM variant of <constant>CP863</constant>.</simpara></listitem>
 <listitem id="charset-CP864"><simpara><constant>CP864</constant>, a DOS oldie,
   &good-for; the Arabic language.</simpara></listitem>
 <listitem id="charset-CP864-IBM"><simpara><constant>CP864-IBM</constant>,
   an IBM variant of <constant>CP864</constant>.
 </simpara></listitem>
 <listitem id="charset-CP865"><simpara><constant>CP865</constant>, a DOS oldie,
   &ascii-pl-ext;, &good-for; some Nordic languages.</simpara></listitem>
 <listitem id="charset-CP865-IBM"><simpara><constant>CP865-IBM</constant>,
   an IBM variant of <constant>CP865</constant>.
 </simpara></listitem>
 <listitem id="charset-CP866"><simpara><constant>CP866</constant>, a DOS oldie,
   &ascii-pl-ext;, &good-for; the Russian language.</simpara></listitem>
 <listitem id="charset-CP869"><simpara><constant>CP869</constant>, a DOS oldie,
   &ascii-pl-ext;, &good-for; the Greek language.</simpara></listitem>
 <listitem id="charset-CP869-IBM"><simpara><constant>CP869-IBM</constant>,
   an IBM variant of <constant>CP869</constant>.
 </simpara></listitem>
 <listitem id="charset-CP874"><simpara><constant>CP874</constant>, a DOS oldie,
   &ascii-pl-ext;, &good-for; the Thai language.</simpara></listitem>
 <listitem id="charset-CP874-IBM"><simpara><constant>CP874-IBM</constant>,
   an IBM variant of <constant>CP874</constant>.
 </simpara></listitem>
 <listitem id="charset-WINDOWS-1250"><simpara><constant>WINDOWS-1250</constant>
   &equiv; <constant>CP1250</constant>,
   &ascii-pl-ext;, heavily incompatible with ISO-8859-2.
 </simpara></listitem>
 <listitem id="charset-WINDOWS-1251"><simpara><constant>WINDOWS-1251</constant>
   &equiv; <constant>CP1251</constant>,
   &ascii-pl-ext;, heavily incompatible with ISO-8859-5,
   &good-for; the Russian language.</simpara></listitem>
 <listitem id="charset-WINDOWS-1252"><simpara><constant>WINDOWS-1252</constant>
   &equiv; <constant>CP1252</constant>,
   a platform specific extension of the ISO-8859-1 character set.
 </simpara></listitem>
 <listitem id="charset-WINDOWS-1253"><simpara><constant>WINDOWS-1253</constant>
   &equiv; <constant>CP1253</constant>,
   &ascii-pl-ext;, gratuitously incompatible with ISO-8859-7,
   &good-for; the Greek language.</simpara></listitem>
 <listitem id="charset-WINDOWS-1254"><simpara><constant>WINDOWS-1254</constant>
   &equiv; <constant>CP1254</constant>,
   a platform specific extension of the ISO-8859-9 character set.
 </simpara></listitem>
<!-- #ifdef GNU_LIBICONV -->
 <listitem id="charset-WINDOWS-1255"><simpara><constant>WINDOWS-1255</constant>
   &equiv; <constant>CP1255</constant>,
   &ascii-pl-ext;, gratuitously incompatible with ISO-8859-8,
   suitable for the Hebrew language.
   &charset-glibc-libiconv;</simpara></listitem>
<!-- #endif /* GNU_LIBICONV */ -->
 <listitem id="charset-WINDOWS-1256"><simpara><constant>WINDOWS-1256</constant>
   &equiv; <constant>CP1256</constant>,
   &ascii-pl-ext;, &good-for; the Arabic language.</simpara></listitem>
 <listitem id="charset-WINDOWS-1257"><simpara><constant>WINDOWS-1257</constant>
   &equiv; <constant>CP1257</constant>,
   &ascii-pl-ext;.</simpara></listitem>
<!-- #ifdef GNU_LIBICONV -->
 <listitem id="charset-WINDOWS-1258"><simpara><constant>WINDOWS-1258</constant>
   &equiv; <constant>CP1258</constant>, &ascii-pl-ext;, &good-for; the
   Vietnamese language. &charset-glibc-libiconv;</simpara></listitem>
<!-- #endif /* GNU_LIBICONV */ -->
 <listitem id="charset-HP-ROMAN8"><simpara><constant>HP-ROMAN8</constant>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-NEXTSTEP"><simpara><constant>NEXTSTEP</constant>,
   &ascii-pl-ext;.</simpara></listitem>
<!-- #ifdef GNU_LIBICONV -->
 <listitem id="charset-EUC-JP"><simpara><constant>EUC-JP</constant>,
   a multibyte character set for the Japanese language.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-SHIFT-JIS"><simpara><constant>SHIFT-JIS</constant>,
   a multibyte character set for the Japanese language.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-CP932"><simpara><constant>CP932</constant>,
   a Microsoft variant of <constant>SHIFT-JIS</constant>.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ISO-2022-JP"><simpara><constant>ISO-2022-JP</constant>,
   a stateful 7-bit multibyte character set for the Japanese language.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ISO-2022-JP-2"><simpara><constant>ISO-2022-JP-2</constant>,
   a stateful 7-bit multibyte character set for the Japanese language.
   This character set is only available on platforms with &glibc; 2.3
   or newer or &libiconv;.</simpara></listitem>
 <listitem id="charset-ISO-2022-JP-1"><simpara><constant>ISO-2022-JP-1</constant>,
   a stateful 7-bit multibyte character set for the Japanese language.
   &charset-libiconv;</simpara></listitem>
 <listitem id="charset-EUC-CN"><simpara><constant>EUC-CN</constant>,
   a multibyte character set for simplified Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-HZ"><simpara><constant>HZ</constant>,
   a stateful 7-bit multibyte character set for simplified Chinese.
   &charset-libiconv;</simpara></listitem>
 <listitem id="charset-GBK"><simpara><constant>GBK</constant>,
   a multibyte character set for Chinese,
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-CP936"><simpara><constant>CP936</constant>,
   a Microsoft variant of <constant>GBK</constant>.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-GB18030"><simpara><constant>GB18030</constant>,
   a multibyte character set for Chinese,
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-EUC-TW"><simpara><constant>EUC-TW</constant>,
   a multibyte character set for traditional Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-BIG5"><simpara><constant>BIG5</constant>,
   a multibyte character set for traditional Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-CP950"><simpara><constant>CP950</constant>,
   a Microsoft variant of <constant>BIG5</constant>.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-BIG5-HKSCS"><simpara><constant>BIG5-HKSCS</constant>,
   a multibyte character set for traditional Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ISO-2022-CN"><simpara><constant>ISO-2022-CN</constant>,
   a stateful 7-bit multibyte character set for Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ISO-2022-CN-EXT"><simpara><constant>ISO-2022-CN-EXT</constant>,
   a stateful 7-bit multibyte character set for Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-EUC-KR"><simpara><constant>EUC-KR</constant>,
   a multibyte character set for Korean.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-CP949"><simpara><constant>CP949</constant>,
   a Microsoft variant of <constant>EUC-KR</constant>.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ISO-2022-KR"><simpara><constant>ISO-2022-KR</constant>,
   a stateful 7-bit multibyte character set for Korean.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-JOHAB"><simpara><constant>JOHAB</constant>,
   a multibyte character set for Korean used mostly on &dos;.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ARMSCII-8"><simpara><constant>ARMSCII-8</constant>,
   &ascii-iso-ext; Armenian. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-GEORGIAN-ACADEMY"><simpara><constant>GEORGIAN-ACADEMY</constant>,
   &ascii-iso-ext; Georgian. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-GEORGIAN-PS"><simpara><constant>GEORGIAN-PS</constant>,
   &ascii-iso-ext; Georgian. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-TIS-620"><simpara><constant>TIS-620</constant>,
   &ascii-iso-ext; Thai. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-MULELAO-1"><simpara><constant>MULELAO-1</constant>,
   &ascii-iso-ext; Laotian. &charset-libiconv;</simpara></listitem>
 <listitem id="charset-CP1133"><simpara><constant>CP1133</constant>,
   &ascii-iso-ext; Laotian. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-VISCII"><simpara><constant>VISCII</constant>,
   &ascii-iso-ext; Vietnamese. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-TCVN"><simpara><constant>TCVN</constant>,
   &ascii-iso-ext; Vietnamese. &charset-glibc-libiconv;</simpara></listitem>
<!-- #endif /* GNU_LIBICONV */ -->
<listitem id="base64"><para><constant>BASE64</constant>, encodes
  arbitrary byte sequences with 64 &ascii; characters <literallayout>
   ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
  </literallayout> as specifined by &mime;; 3 bytes are encoded with 4
  characters, line breaks are inserted after every 76 characters.</para>
 <simpara>While this is not a traditional character set (i.e., it does
  not map a set of characters in a natural language into bytes), it
  does define a map between arbitrary byte sequences and certain
  character sequences, so it falls naturally into the &encoding; class.
</simpara></listitem>
</orderedlist>

<!-- #ifdef /* HAVE_ICONV */ -->
<variablelist>
<varlistentry id="iconv"><term><emphasis role="plat-dep">Only on &gnu; systems
  with &glibc; 2.2 or better and other systems (&unix; and &win32;)
  on which the &libiconv; &c-lang; library has been installed</emphasis></term>
<listitem><simpara>The character sets provided by the library function
 &iconv; can also be used as encodings.  To create such an encoding,
 call &make-encoding; with the character set name (a string) as the
 <constant>:CHARSET</constant> argument.</simpara>

<simpara>When an &encoding; is available both as a &enc-built-in; and
 through &iconv;, the &enc-built-in; is used, because it is more
 efficient and available across all platforms.</simpara>

<simpara>These encodings are not assigned to global variables, since
 there is no portable way to get the list of all character sets
 supported by &iconv;.</simpara>

<simpara>On standard-compliant &unix; systems (e.g., &gnu; systems, such
 as &gnu;/&linux; and &gnu;/&hurd;) and on systems with &libiconv; you
 get this list by calling the <emphasis>program</emphasis>:
 <command role="unix">iconv -l</command>.</simpara>

<simpara>The reason we use only &glibc; 2.2 or &libiconv; is
 that the other &iconv; implementations are broken in various ways and
 we do not want to deal with random &clisp; crashes caused by those bugs.
 If your system supplies an &iconv; implementation which passes the
 &libiconv;'s test suite, please report that
 to <ulink url="ml">clisp-list</ulink> and a
 future &clisp; version will use &iconv; on your system.</simpara>

</listitem></varlistentry></variablelist>
<!-- #endif /* HAVE_ICONV */ -->
</para></listitem></varlistentry>

<!-- #endif /* ENABLE_UNICODE */ -->
</variablelist>

</section>

<section id="newline"><title>Line Terminators</title>

<para>The line terminator mode can be one of the following three keywords:
<variablelist>
<varlistentry><term>&unix-k;</term>
 <listitem><simpara>Newline is represented by the &ascii;
   &lf-c; character (<keycode>U000A</keycode>).
</simpara></listitem></varlistentry>
<varlistentry><term>&mac-k;</term>
 <listitem><simpara>Newline is represented by the &ascii;
   &cr-c; character (<keycode>U000D</keycode>).
</simpara></listitem></varlistentry>
<varlistentry><term>&dos-k;</term>
 <listitem><simpara>Newline is represented by the &ascii;
   &cr-c; followed by the &ascii; &lf-c;.
</simpara></listitem></varlistentry></variablelist></para>

<para>Windows programs typically use the &dos-k; line terminator,
 sometimes they also accept &unix-k; line terminators or produce
 &mac-k; line terminators.</para>

<para>The &http; protocol also requires &dos-k; line terminators.</para>

<para>The line terminator mode is relevant only for output (writing to a
 &file-pipe-socket-s;).  During input, all three kinds of line terminators
 are recognized.  See also <xref linkend="clhs-newline"/>.</para>

</section>

<section id="make-encoding"><title>Function &make-encoding;</title>

<para>The function <code>(&make-encoding; &key-amp; :CHARSET
     :LINE-TERMINATOR :INPUT-ERROR-ACTION :OUTPUT-ERROR-ACTION)</code>
 returns an &encoding;. The <constant>:CHARSET</constant> argument may be
 an encoding, a string, or &default-k;.
 The possible values for the &line-term; argument are the
 keywords &unix-k;, &mac-k;, &dos-k;.</para>

<para>The <constant>:INPUT-ERROR-ACTION</constant> argument specifies
 what happens when an invalid byte sequence is encountered while
 converting bytes to characters.  Its value can be &error-k;, &ignore-k;
 or a character to be used instead.  The &unicode; character
 <keysym>#\uFFFD</keysym> is typically used to indicate an error in the
 input sequence.</para>

<para>The <constant>:OUTPUT-ERROR-ACTION</constant> argument specifies
 what happens when an invalid character is encountered while converting
 characters to bytes.  Its value can be &error-k;, &ignore-k;, a byte to
 be used instead, or a character to be used instead.  The &unicode;
 character <keysym>#\uFFFD</keysym> can be used here only if it is
 encodable in the character set.</para>

</section>

<section id="enc-charset"><title>Function &enc-charset;</title>
<subtitle>&unicode-only;</subtitle>

<para>The function <code>(&enc-charset; &encoding-r;)</code> returns the
 charset of the &encoding-r;, as a &symbol-t; or a &string-t;.</para>

<warning><para><code>(&string; (&enc-charset; &encoding-r;))</code> is
  not necessarily a valid &mime; name.</para></warning>

</section>

<section id="enc-dflt"><title>Default encodings</title>

<para>Besides every &file-pipe-socket-s; containing an encoding,
 the following &symbol-macro; places contain global &encoding;s:</para>

<formalpara id="def-file-enc"><title>&symbol-macro; &def-file-enc;</title>
<para>The &symbol-macro; &place; &def-file-enc; is the encoding used for
 new &file-pipe-socket-s;, when no &extfmt; argument was specified.
</para></formalpara>

<!-- #ifdef ENABLE_UNICODE -->
<variablelist>
<varlistentry><term>&unicode-only;</term>
<listitem><simpara>The following are &symbol-macro; places.</simpara>
<variablelist>
<varlistentry><term><firstterm>&path-enc;
   <indexterm id="path-enc" significance="preferred">
    <primary><varname>*PATHNAME-ENCODING*</varname>
 </primary></indexterm></firstterm></term>
 <listitem><para>is the encoding used for converting filenames in the
   file system (represented with byte sequences by the OS) to lisp
   &pathname-t; components (&string-t;s).
   If this encoding is incompatible with some file names on your system,
   file system access (e.g., &directory;) may &signal; &error-t;s,
   thus extreme caution is recommended if this is &not-e; a &enc1-1;.
   Sometimes it may not be obvious that the encoding is involved at all.
   E.g., on &win32;: <programlisting language="lisp">
(&parse-namestring; (&string; #\ARMENIAN_SMALL_LETTER_RA))
*** - PARSE-NAMESTRING: syntax error in filename "&#x57C;" at position 0
</programlisting>when &path-enc; is &utf-16; because then
   <literal role="data">#\ARMENIAN_SMALL_LETTER_RA</literal> corresponds
   to the 4 bytes <literal role="data">#(255 254 124 5)</literal>
   and the byte <literal role="data">124</literal> is &not-e; a valid
   byte for a &win32; file name because it
   means <literal role="data">|</literal> in &ascii;.</para>
  <simpara>The set of valid pathname <emphasis>bytes</emphasis> is
   determined by the &autoconf; test
   <filename role="clisp-cvs">src/m4/filecharset.m4</filename>
   at configure time. While rather stable for the first 127 bytes,
   on &win32; it varies wildly for the bytes 128-256, depending on the
   OS version and the file system.</simpara>
  <simpara>The &line-term; mode of &path-enc; is ignored.</simpara>
  <simpara><emphasis role="plat-dep">&macosx; platform only</emphasis>:
   &macosx; pathnames are actually &unicode; &string-t;s, so
   &path-enc; is a constant with value &utf-8;.</simpara>
</listitem></varlistentry>
<varlistentry><term><firstterm>&term-enc;
   <indexterm id="term-enc" significance="preferred">
    <primary><varname>*TERMINAL-ENCODING*</varname>
 </primary></indexterm></firstterm></term>
 <listitem><simpara>is the encoding used for communication with the
  terminal, in particular by &terminal-io-var;.
 </simpara></listitem></varlistentry>
<varlistentry><term><firstterm>&misc-enc;
   <indexterm id="misc-enc" significance="preferred">
    <primary><varname>*MISC-ENCODING*</varname>
 </primary></indexterm></firstterm></term>
 <listitem><simpara>is the encoding used for access to &env-var;s,
 command line options, and the like.  Its &line-term; mode is ignored.
 </simpara></listitem></varlistentry>
<!-- #if defined(DYNAMIC_FFI) -->
<varlistentry><term><firstterm>&foreign-enc;
   <indexterm id="foreign-enc" significance="preferred">
    <primary><varname>*FOREIGN-ENCODING*</varname>
 </primary></indexterm></firstterm></term>
 <listitem><simpara>is the encoding for strings passed through the
 &ffi-pac; (some platforms only). If it is a &enc1-1;,
 i.e. an encoding in which every character is represented by one byte,
 it is also used for passing characters through the &ffi-pac;.
</simpara></listitem></varlistentry>
<!-- #endif -->
</variablelist></listitem></varlistentry>
</variablelist>
<!-- #endif -->

<para>The default encoding objects are initialized according to &opt-E;.</para>

<note><title>Reminder</title><para>You have to use &letf;/&letf-star;
  for &symbol-macro;s; &let;/&let-star; will &not-e; work!</para></note>

<section id="line-term-default"><title>Default &line-term;</title>
<para>The &line-term; facet of the above &encoding;s is determined by
 the following logic: since &clisp; understands all possible
 &line-term;s on <emphasis>input</emphasis> (see
 <xref linkend="clhs-newline"/>), all that matters is what &line-term;
 do most <emphasis>other</emphasis> programs expect?</para>

<variablelist>
<!-- #ifdef UNIX -->
<varlistentry><term>&unix-only;</term>
 <listitem><simpara>If a non-0 <literal>O_BINARY</literal> &cpp;
   constant is defined, we assume that the OS distinguishes between text
   and binary files, and, since the encodings are relevant only for text
   files, we thus use &dos-k;; otherwise the default is &unix-k;.
</simpara></listitem></varlistentry>
<!-- #endif -->
<!-- #ifdef WIN32 -->
<varlistentry><term>&win32-only;</term>
 <listitem><simpara>Since most &win32; programs expect CRLF, the default
  &line-term; is &dos-k;.</simpara></listitem></varlistentry>
<!-- #endif -->
</variablelist>

<para>This boils down to the following code
 in <filename role="clisp-cvs">src/encoding.d</filename>:
<programlisting language="C">
 #if defined(WIN32) || (defined(UNIX) &amp;&amp; (O_BINARY != 0))
</programlisting></para>

<note id="cygwin-line-term-default"><title>Default &line-term; on
  &cygwin;</title><para><emphasis>Both</emphasis> of the above tests
  pass on &cygwin;, so the default &line-term; is &dos-k;.
  If you so desire, you can change it in your &RC-file;.</para></note>
</section>

</section>

<section id="string-byte">
   <title>Converting between strings and byte vectors</title>

<para>Encodings can also be used to convert directly between strings and
their corresponding byte vector representation according to that encoding.
</para>

<variablelist>

<varlistentry><term><code>(&convert-string-from-bytes;
      &vec-r; &encoding-r; &key-amp; &start-k; &end-k;)</code></term>
 <listitem><simpara>converts the subsequence of &vec-r; (a &ubyte-vec;)
   from &start-r; to &end-r; to a &string-t;, according to the given
   &encoding-r;, and returns the resulting string.
</simpara></listitem></varlistentry>

<varlistentry><term><code>(&convert-string-to-bytes;
      &string-r; &encoding-r; &key-amp; &start-k; &end-k;)</code></term>
 <listitem><simpara>converts the subsequence of &string-r; from
   &start-r; to &end-r; to a &ubyte-vec;, according to the given
   &encoding-r;, and returns the resulting byte vector.
</simpara></listitem></varlistentry>

</variablelist>

</section>
</section>

<!-- #ifdef GENERIC_STREAMS -->
<section id="gstream"><title>Generic streams</title>

<para>This interface is &clisp;-specific and now obsolete.  Please use
 the <link linkend="gray">Gray streams</link> interface instead.</para>

<para>Generic streams are user programmable streams.
 The programmer interface:</para>

<variablelist>
 <varlistentry><term><code>(<function>gstream:make-generic-stream</function>
                 <replaceable>controller</replaceable>)</code></term>
  <listitem><simpara>returns a generic stream.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>gstream:generic-stream-controller</function>
                 &stream-r;)</code></term>
  <listitem><simpara>returns a private object to which generic stream
   methods dispatch.  The typical usage is to retrieve the object
   originally provided by the user in
   <function>gstream:make-generic-stream</function>.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>gstream:generic-stream-p</function>
                 &stream-r;)</code></term>
  <listitem><simpara>determines whether a stream is a generic stream,
   returning &t; if it is, &nil; otherwise.
  </simpara></listitem></varlistentry>
</variablelist>

<para>In order to specify the behavior of a generic stream, the user
 must define &clos; methods on the following &clos; generic
 functions.  The function <function>gstream:generic-stream-&x-r;</function>
 corresponds to the &cl; function <function>&x-r;</function>.
 They all take a controller and some number of arguments.</para>

<variablelist>
 <varlistentry><term><code>(gstream:generic-stream-read-char
                 <replaceable>controller</replaceable>)</code></term>
  <listitem><simpara> Returns and consumes the next character, &nil; at
    end of file.  Takes one argument, the controller object.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(gstream:generic-stream-peek-char
                 <replaceable>controller</replaceable>)</code></term>
  <listitem><simpara> Returns the next character, &nil; at end of file.  A
   second value indicates whether the side effects associated with
   consuming the character were executed: &t; means that a full
   &read-char; was done, &nil; means that no side effects were done.
   Takes one argument, the controller object.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(gstream:generic-stream-read-byte
                 <replaceable>controller</replaceable>)</code></term>
  <listitem><simpara>Returns and consumes the next integer, &nil; at end
   of file.  Takes one argument, the controller object.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(gstream:generic-stream-read-char-will-hang-p
     <replaceable>controller</replaceable>)</code></term>
  <listitem><simpara>This generic function is used to query the stream's
   input status.  It returns &nil; if
   <function>gstream:generic-stream-read-char</function> and
   <function>gstream:generic-stream-peek-char</function> will certainly
   return immediately.  Otherwise it returns true.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(gstream:generic-stream-write-char
                 <replaceable>controller</replaceable> &ch-r;)</code></term>
  <listitem><simpara>The first argument is the controller object.
   The second argument is the character to be written.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(gstream:generic-stream-write-byte
                 <replaceable>controller</replaceable>
                 <replaceable>by</replaceable>)</code></term>
  <listitem><simpara>The first argument is the controller object.
   The second argument is the integer to be written.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(gstream:generic-stream-write-string
                 <replaceable>controller</replaceable>
                 &string-r; &start-r; &len-r;)</code></term>
  <listitem><simpara>Writes the subsequence of &string-r; starting from
   &start-r; of length &len-r;.
   The first argument is the controller object.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(gstream:generic-stream-clear-input
                 <replaceable>controller</replaceable>)</code></term>
  <term><code>(gstream:generic-stream-clear-output
     <replaceable>controller</replaceable>)</code></term>
  <term><code>(gstream:generic-stream-finish-output
     <replaceable>controller</replaceable>)</code></term>
  <term><code>(gstream:generic-stream-force-output
     <replaceable>controller</replaceable>)</code></term>
  <term><code>(gstream:generic-stream-close
     <replaceable>controller</replaceable>)</code></term>
  <listitem><simpara>Take one argument, the controller object.
 </simpara></listitem></varlistentry>
</variablelist>
</section>
<!-- #endif -->

<section id="weak"><title>Weak Objects</title>

<para>Recall two terms: An object is called <quote>"alive"</quote> as
 long as it can be retrieved by the user or program, through any kind of
 references, starting from global and local variables. (Objects that
 consume no heap storage, also known as <quote>"immediate
 objects"</quote>, such as &character-t;s, &fixnum-t;s, and
 &short-float-t;s, are alive indefinitely.) An object is said to be
 &gc;ed when its storage is reclaimed, at some moment after it becomes
 <quote>"dead"</quote>.</para>

<section id="weak-pointer"><title>Weak Pointers</title>

<para>A &weak-pointer; is an object holding a reference to a given object,
 without keeping the latter from being &gc;ed.</para>

<variablelist><title>Weak Pointer API</title>
<varlistentry>
 <term><code>(<function>EXT:MAKE-WEAK-POINTER</function>
   &value-r;)</code></term>
 <listitem><simpara>returns a &fresh; &weak-pointer; referring to
   &value-r;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-POINTER-P</function> &object-r;)</code></term>
 <listitem><simpara>returns true if the &object-r; is of type
   &weak-pointer;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-POINTER-VALUE</function>
   <replaceable>weak-pointer</replaceable>)</code></term>
 <listitem><simpara>returns two values: The original value and &t;,
   if the value has not yet been &gc;ed, else &nil; and &nil;.
   It is &setf;-able: you can change the value that the weak pointer
   points to.</simpara></listitem></varlistentry>
</variablelist>

<para>Weak pointers are useful for notification-based communication
 protocols between software modules, e.g. when a change to an object
 &x-r; requires a notification to an object &y-r;, as long as &y-r; is
 alive.</para>

</section>

<section id="weak-list"><title>Weak Lists</title>

<para>A &weak-list; is an ordered collection of references to objects
 that does &not-e; keep the objects from being &gc;ed. It is
 semantically equivalent to a list of &weak-pointer;s, however with a
 more efficient in-memory representation than a plain list of
 &weak-pointer;s would be.</para>

<variablelist><title>Weak List API</title>
<varlistentry>
 <term><code>(<function>EXT:MAKE-WEAK-LIST</function> &list-r;)</code></term>
 <listitem><simpara>creates a &weak-list; pointing to each of the
   elements in the given &list-r;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-LIST-P</function> &object-r;)</code></term>
 <listitem><simpara>returns true if the &object-r; is of type
   &weak-list;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-LIST-LIST</function>
   <replaceable>weak-list</replaceable>)</code></term>
 <listitem><simpara>returns a &list-t; of those objects from the
   <replaceable>weak-list</replaceable> that are still
   alive.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(&setf; (<function>EXT:WEAK-LIST-LIST</function>
   <replaceable>weak-list</replaceable>) &list-r;)</code></term>
 <listitem><simpara>replaces the list of objects stored by the
   <replaceable>weak-list</replaceable>.</simpara></listitem></varlistentry>
</variablelist>

<para>Weak lists are useful for notification based communication
 protocols between software modules, e.g. when a change to an object
 &x-r; requires a notification to objects &k1-r;, &k2-r;, ..., as long
 as such a particular &kn-r; is alive.</para>

<para>A &weak-list; with a single element is semantically equivalent to a
 single &weak-pointer;.</para>

</section>

<section id="weak-and-relation"><title>Weak <quote>And</quote> Relations</title>

<para>A weak <quote>and</quote> relation is an ordered collection of
 references to objects, that does &not-e; keep the objects from being
 &gc;ed, and which allows access to all the objects as long as all of
 them are still alive. As soon as one of them is &gc;ed, the entire
 collection of objects becomes empty.</para>

<variablelist><title>Weak <quote>And</quote> Relation API</title>
<varlistentry>
 <term><code>(<function>EXT:MAKE-WEAK-AND-RELATION</function>
   &list-r;)</code></term>
 <listitem><simpara>creates a &weak-and-relation; between the objects in
   the given &list-r;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-AND-RELATION-P</function>
   &object-r;)</code></term>
 <listitem><simpara>returns true if the &object-r; is of type
   &weak-and-relation;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-AND-RELATION-LIST</function>
   <replaceable>weak-and-relation</replaceable>)</code></term>
 <listitem><simpara>returns the list of objects stored in the
   <replaceable>weak-and-relation</replaceable>. The returned list must not
   be destructively modified.</simpara></listitem></varlistentry>
</variablelist>

<para>&weak-and-relation;s are useful to model relations between objects
 that become worthless when one of the objects dies.</para>

<para>A &weak-and-relation; with a single element is semantically
 equivalent to a &weak-pointer;.</para>

</section>

<section id="weak-or-relation"><title>Weak <quote>Or</quote> Relations</title>

<para>A weak <quote>or</quote> relation is an ordered collection of
 references to objects, that keeps all objects from being &gc;ed as long
 as one of them is still alive. In other words, each of them keeps all
 others among them from being &gc;ed. When all of them are unreferenced,
 the collection of objects becomes empty.</para>

<variablelist><title>Weak <quote>Or</quote> Relation API</title>
<varlistentry>
 <term><code>(<function>EXT:MAKE-WEAK-OR-RELATION</function>
   &list-r;)</code></term>
 <listitem><simpara>creates a &weak-or-relation; between the objects in
   the given &list-r;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-OR-RELATION-P</function>
   &object-r;)</code></term>
 <listitem><simpara>returns true if the &object-r; is of type
   &weak-or-relation;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-OR-RELATION-LIST</function>
   <replaceable>weak-or-relation</replaceable>)</code></term>
 <listitem><simpara>returns the list of objects stored in the
   <replaceable>weak-or-relation</replaceable>. The returned list must not
   be destructively modified.</simpara></listitem></varlistentry>
</variablelist>

<para>&weak-or-relation;s are useful to model relations between objects
 that do not become worthless when one of the objects dies.</para>

<para>A &weak-or-relation; with a single element is semantically
 equivalent to a &weak-pointer;.</para>

</section>

<section id="weak-mapping"><title>Weak Associations</title>

<para>A weak association is a mapping from an object called &key-r; to
 an object called &value-r;, that exists as long as the key is alive. In
 other words, as long as the key is alive, it keeps the value from being
 &gc;ed.</para>

<variablelist><title>Weak Association API</title>
<varlistentry>
 <term><code>(<function>EXT:MAKE-WEAK-MAPPING</function>
   &key-r; &value-r;)</code></term>
 <listitem><simpara>creates a &weak-mapping;.
</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-MAPPING-P</function>
   &object-r;)</code></term>
 <listitem><simpara>returns true if the object is of type
   &weak-mapping;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-MAPPING-PAIR</function>
   <replaceable>weak-mapping</replaceable>)</code></term>
 <listitem><simpara>returns three values: the original key, the original
   value, and &t;, if the key has not yet been &gc;ed, else &nil;, &nil;,
   &nil;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-MAPPING-VALUE</function>
   <replaceable>weak-mapping</replaceable>)</code></term>
 <listitem><simpara>returns the value, if the key has not yet been &gc;ed,
   else &nil;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(&setf; (<function>EXT:WEAK-MAPPING-VALUE</function>
   <replaceable>weak-mapping</replaceable>) &value-r;)</code></term>
 <listitem><simpara>replaces the value stored in the
   <replaceable>weak-mapping</replaceable>. It has no effect when the
   key has already been &gc;ed.</simpara></listitem></varlistentry>
</variablelist>

<para>Weak associations are useful to supplement objects with additional
 information that is stored outside of the object.</para>

</section>

<section id="weak-and-mapping"><title>Weak <quote>And</quote> Mappings</title>

<para>A weak <quote>and</quote> mapping is a mapping from a tuple of
 objects called &keys-r; to an object called &value-r;, that does
 &not-e; keep the keys from being &gc;ed and that exists as long as all
 keys are alive. As soon as one of the keys is &gc;ed, the entire
 mapping goes away.</para>

<variablelist><title>Weak <quote>And</quote> Mapping API</title>
<varlistentry>
 <term><code>(<function>EXT:MAKE-WEAK-AND-MAPPING</function>
   &keys-r; &value-r;)</code></term>
 <listitem><simpara>creates a &weak-and-mapping; between the &keys-r;
   objects in the given list and the given &value-r;.
   The &keys-r; list must be non-empty.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-AND-MAPPING-P</function>
   &object-r;)</code></term>
 <listitem><simpara>returns true if the &object-r; is of type
   &weak-and-mapping;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-AND-MAPPING-PAIR</function>
   <replaceable>weak-and-mapping</replaceable>)</code></term>
 <listitem><simpara>returns three values: the list of keys, the value,
   and &t;, if none of the keys have been &gc;ed, else &nil;, &nil;, &nil;.
   The returned keys list must not be destructively modified.
</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-AND-MAPPING-VALUE</function>
   <replaceable>weak-and-mapping</replaceable>)</code></term>
 <listitem><simpara>returns the value, if none of the keys have been
   &gc;ed, else &nil;.</simpara></listitem></varlistentry>
<varlistentry> <term><code>(&setf;
   (<function>EXT:WEAK-AND-MAPPING-VALUE</function>
   <replaceable>weak-and-mapping</replaceable>) &value-r;)</code></term>
 <listitem><simpara>replaces the value stored in the
   <replaceable>weak-and-mapping</replaceable>. It has no effect when
   some key has already been &gc;ed.</simpara></listitem></varlistentry>
</variablelist>

<para>&weak-and-mapping;s are useful to model properties of sets of
 objects that become worthless when one of the objects dies.</para>

<para>A &weak-and-mapping; with a single key is semantically equivalent
 to a weak association.</para>

</section>

<section id="weak-or-mapping"><title>Weak <quote>Or</quote> Mappings</title>

<para>A weak <quote>or</quote> mapping is a mapping from a tuple of
 objects called &keys-r; to an object called &value-r;, that keeps all
 keys and the value from being &gc;ed as long as one of the keys is
 still alive. In other words, each of the keys keeps all others among
 them and the value from being &gc;ed.  When all of them are
 unreferenced, the entire mapping goes away.</para>

<variablelist><title>Weak <quote>Or</quote> Mapping API</title>
<varlistentry>
 <term><code>(<function>EXT:MAKE-WEAK-OR-MAPPING</function>
   &keys-r; &value-r;)</code></term>
 <listitem><simpara> creates a &weak-or-mapping; between the
   &keys-r; objects in the given list and the given
   &value-r;. The &keys-r; list must be
   non-empty.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-OR-MAPPING-P</function>
   &object-r;)</code></term>
 <listitem><simpara>returns true if the &object-r; is of type
   &weak-or-mapping;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-OR-MAPPING-PAIR</function>
   <replaceable>weak-or-mapping</replaceable>)</code></term>
 <listitem><simpara>returns three values: the list of keys, the value,
   and &t;, if the keys have not yet been &gc;ed, else &nil;, &nil;, &nil;.
   The returned keys list must not be destructively modified.
</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-OR-MAPPING-VALUE</function>
   <replaceable>weak-or-mapping</replaceable>)</code></term>
 <listitem><simpara>returns the value, if the keys have not yet been &gc;ed,
   else &nil;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(&setf; (<function>EXT:WEAK-OR-MAPPING-VALUE</function>
   <replaceable>weak-or-mapping</replaceable>) &value-r;)</code></term>
 <listitem><simpara>replaces the value stored in the
   <replaceable>weak-or-mapping</replaceable>. It has no effect when the
   keys have already been &gc;ed.</simpara></listitem></varlistentry>
</variablelist>

<para>&weak-or-mapping;s are useful to model properties of sets of
 objects that do not become worthless when one of the objects dies.</para>

<para>A &weak-or-mapping; with a single key is semantically equivalent
 to a weak association.</para>

</section>

<section id="weak-alist"><title>Weak Association Lists</title>

<para>A weak association list is an ordered collection of pairs, each
 pair being built from an object called &key-r; and an object called
 &value-r;.  The lifetime of each pair depends on the type of the weak
 &alist;:
<variablelist>
 <varlistentry><term>&key-k;</term>
  <listitem><simpara>The pair exists as long as the &key-r; is not &gc;ed.
    As long as the &key-r; is alive, it prevents the &value-r; from
    being &gc;ed.</simpara></listitem></varlistentry>
 <varlistentry><term>&value-k;</term>
  <listitem><simpara>The pair exists as long as the &value-r; is not &gc;ed.
   As long as the &value-r; is alive, it prevents the &key-r; from
   being &gc;ed.</simpara></listitem></varlistentry>
 <varlistentry><term>&key-and-value-k;</term>
  <listitem><simpara>The pair exists as long as the &key-r; and the &value-r;
   are alive.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&key-or-value-k;</term>
  <listitem><simpara>The pair exists as long as the &key-r; or the &value-r;
   are alive.  As long as the &key-r; is alive, it prevents the &value-r;
   from being &gc;ed, and as long as the &value-r; is alive, it prevents the
   &key-r; from being &gc;ed.</simpara></listitem></varlistentry>
</variablelist>
In other words, each pair is:
<variablelist>
 <varlistentry><term>&key-k;</term>
  <listitem><simpara>a &weak-mapping; from the &key-r; to the &value-r;,
 </simpara></listitem></varlistentry>
 <varlistentry><term>&value-k;</term>
  <listitem><simpara>a &weak-mapping; from the &value-r; to the &key-r;,
 </simpara></listitem></varlistentry>
 <varlistentry><term>&key-and-value-k;</term>
  <listitem><simpara>a &weak-and-relation; of the &key-r; and the &value-r;,
 </simpara></listitem></varlistentry>
 <varlistentry><term>&key-or-value-k;</term>
  <listitem><simpara>a &weak-or-relation; of the &key-r; and the &value-r;.
 </simpara></listitem></varlistentry>
</variablelist></para>

<variablelist><title>Weak Association List API</title>
<varlistentry>
 <term><code>(<function>EXT:MAKE-WEAK-ALIST</function>
   :type :initial-contents)</code></term>
 <listitem><simpara>creates a &weak-alist;. The &type-r; argument
   must be one of the four aforementioned types; the default is &key-k;.
   The <replaceable>initial-contents</replaceable> argument must be an
   &alist;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-ALIST-P</function> &object-r;)</code></term>
 <listitem><simpara>returns true if the &object-r; is of type
   &weak-alist;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-ALIST-TYPE</function>
   <replaceable>weak-alist</replaceable>)</code></term>
 <listitem><simpara>returns the type of the
   <replaceable>weak-alist</replaceable>.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-ALIST-CONTENTS</function>
   <replaceable>weak-alist</replaceable>)</code></term>
 <listitem><simpara>returns an &alist; that corresponds to the current
   contents of the <replaceable>weak-alist</replaceable>.
</simpara></listitem></varlistentry>
<varlistentry><term><code>(&setf; (<function>EXT:WEAK-ALIST-CONTENTS</function>
   <replaceable>weak-alist</replaceable>)
   <replaceable>contents</replaceable>)</code></term>
 <listitem><simpara>replaces the contents of a
   <replaceable>weak-alist</replaceable>. The
   <replaceable>contents</replaceable> argument must be an
   &alist;.</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-ALIST-ASSOC</function> &item-r;
   <replaceable>weak-alist</replaceable>
   [:test] [:test-not] [:key])</code></term>
 <listitem><simpara>is equivalent to
   <code>(&assoc; &item-r; (<function>EXT:WEAK-ALIST-CONTENTS</function>
    <replaceable>weak-alist</replaceable>)
    [:test] [:test-not] [:key])</code>.
</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-ALIST-RASSOC</function> &item-r;
   <replaceable>weak-alist</replaceable>
   [:test] [:test-not] [:key])</code></term>
 <listitem><simpara>is equivalent to
   <code>(&rassoc; &item-r; (<function>EXT:WEAK-ALIST-CONTENTS</function>
    <replaceable>weak-alist</replaceable>)
    [:test] [:test-not] [:key])</code>.
</simpara></listitem></varlistentry>
<varlistentry>
 <term><code>(<function>EXT:WEAK-ALIST-VALUE</function> &item-r;
   <replaceable>weak-alist</replaceable> [:test] [:test-not])</code></term>
 <listitem><simpara>is equivalent to
   <code>(&cdr; (<function>EXT:WEAK-LIST-ASSOC</function>
    &item-r; <replaceable>weak-alist</replaceable>
    [:test] [:test-not]))</code>.
</simpara></listitem></varlistentry>
<varlistentry><term><code>(&setf; (<function>EXT:WEAK-ALIST-VALUE</function>
   &item-r; <replaceable>weak-alist</replaceable> [:test] [:test-not])
   &value-r;)</code></term>
 <listitem><simpara>replaces the value stored for &item-r; in
   a <replaceable>weak-alist</replaceable>.  When a pair with the given
   &item-r; as key does not exist or has already been &gc;ed, a new pair
   is added to the &alist;.</simpara></listitem></varlistentry>
</variablelist>

<para>Weak associations lists are useful to supplement objects with
 additional information that is stored outside of the object, when the
 number of such objects is known to be small.</para>

</section>

<section id="weak-ht"><title>Weak Hash Tables</title>

<para>A weak &hash-table-t; is an unordered collection of pairs, each
 pair being built from an object called &key-r; and an object called
 &value-r;. There can be only one pair with a given &key-r; in a weak
 &hash-table-t;. The lifetime of each pair depends on the type of the
 weak &hash-table-t;
<variablelist>
 <varlistentry><term>&key-k;</term>
  <listitem><simpara>The pair exists as long as the &key-r; is not &gc;ed.
    As long as the &key-r; is alive, it prevents the &value-r; from
    being &gc;ed.</simpara></listitem></varlistentry>
  <varlistentry><term>&value-k;</term>
   <listitem><simpara>The pair exists as long as the &value-r; is not &gc;ed.
     As long as the &value-r; is alive, it prevents the &key-r; from
     being &gc;ed.</simpara></listitem></varlistentry>
  <varlistentry><term>&key-and-value-k;</term>
   <listitem><simpara>The pair exists as long as the &key-r; and the
     &value-r; are alive.</simpara></listitem></varlistentry>
  <varlistentry><term>&key-or-value-k;</term>
   <listitem><simpara>The pair exists as long as the &key-r; or the
     &value-r; are alive.  As long as the &key-r; is alive, it prevents
     the &key-r; from being &gc;ed, and as long as the &value-r; is
     alive, it prevents the &key-r; from being &gc;ed.
  </simpara></listitem></varlistentry>
</variablelist>
In other words, each pair is:
<variablelist>
 <varlistentry><term>&key-k;</term>
  <listitem><simpara>a &weak-mapping; from the &key-r; to the &value-r;,
 </simpara></listitem></varlistentry>
 <varlistentry><term>&value-k;</term>
  <listitem><simpara>a &weak-mapping; from the &value-r; to the &key-r;,
 </simpara></listitem></varlistentry>
 <varlistentry><term>&key-and-value-k;</term>
  <listitem><simpara>a &weak-and-relation; of the &key-r; and the &value-r;,
 </simpara></listitem></varlistentry>
 <varlistentry><term>&key-or-value-k;</term>
  <listitem><simpara>a &weak-or-relation; of the &key-r; and the &value-r;.
</simpara></listitem></varlistentry></variablelist></para>

<para>See also <xref linkend="make-hash"/>.</para>

<para>Weak &hash-table-t;s are useful to supplement objects with
 additional information that is stored outside of the object. This data
 structure scales up without performance degradation when the number of
 pairs is big.</para>

<para>Weak &hash-table-t;s are also useful to implement canonicalization
 tables.</para>

</section>
</section>


<section id="final"><title>Finalization</title>

<para>Calling <code>(&finalize; &object-r; &func-r;)</code>
 has the effect that when the specified object is being &gc;ed,
 <code>(&funcall; &func-r; &object-r;)</code> will be executed.</para>

<para>Calling <code>(&finalize; &object-r; &func-r; &guardian-r;)</code>
 has a similar effect, but only as long as the &guardian-r; has not been &gc;ed:
 when &object-r; is being &gc;ed, <code>(&funcall; &func-r; &object-r;
 &guardian-r;)</code> will be executed.
 If the &guardian-r; is &gc;ed before &object-r; is, nothing happens.</para>

<note><title>Note</title>
 <para>The time when <quote>the &object-r; is being &gc;ed</quote> is not
  defined deterministically.  (Actually, it might possibly never occur.)
  It denotes a moment at which no references to &object-r; exist from other
  Lisp objects.  When the &func-r; is called, &object-r; (and, possibly,
  &guardian-r;) enter the <quote>arena of live Lisp objects</quote> again.
</para></note>

<para>No finalization request will be executed more than once.</para>

</section>


<section id="prompt"><title>The Prompt</title>

<para>&clisp; prompt consists of 3 mandatory parts: <quote>start</quote>,
 <quote>body</quote>, and <quote>finish</quote>; and 2 optional parts:
 <quote>break</quote>, which appears only in the &debugger; (after &break;
 or &error;), and <quote>step</quote>, which appears only in the &step;er.
 Each part is controlled by a custom variable, which can be either a
 &string-t; or a &function-t; of no arguments returning a &string-t;
 (if it is something else - or if the return value was not a &string-t;
 - it is printed with &princ;).  In the order of invocation:<variablelist>
  <varlistentry id="prompt-start"><term>&prompt-start;</term>
   <listitem><simpara>Defaults to an empty string.
  </simpara></listitem></varlistentry>
  <varlistentry id="prompt-step"><term>&prompt-step;</term>
   <listitem><simpara>Used only during &step;ping.
     Defaults to <quote><prompt>Step n&nbsp;</prompt></quote>,
     where &n-r; is the stepping level as returned by &step-level;.
  </simpara></listitem></varlistentry>
  <varlistentry id="prompt-break"><term>&prompt-break;</term>
   <listitem><simpara>Used only inside break loop (during debugging).
     Defaults to <quote><prompt>Break n&nbsp;</prompt></quote>,
     where &n-r; is the break level as returned by &break-level;.
  </simpara></listitem></varlistentry>
  <varlistentry id="prompt-body"><term>&prompt-body;</term>
   <listitem><simpara>Defaults to <quote><prompt>package[n]</prompt></quote>
     where &pack-r; is the shortest (nick)name (as returned by
     &package-shortest-name;) of the current package &package-var;
     if it is &not-e; the same as it was in the beginning
     (determined by &prompt-new-package;)
     or if it does not contain symbol &t;,
     (it is assumed that in the latter case you would want to keep in
     mind that your current package is something weird);
     and &n-r; is the index of the current prompt, kept in &command-index;.
  </simpara></listitem></varlistentry>
  <varlistentry id="prompt-finish"><term>&prompt-finish;</term>
   <listitem><simpara>Defaults to <quote><prompt>&gt;&nbsp;</prompt></quote>.
</simpara></listitem></varlistentry></variablelist></para>

<para>To facilitate your own custom prompt creation, the following
 functions and variables are available:<variablelist>
  <varlistentry id="break-level"><term>&break-level;</term>
   <listitem><simpara>This &function-t; returns current &break;/&error; level.
  </simpara></listitem></varlistentry>
  <varlistentry id="step-level"><term>&step-level;</term>
   <listitem><simpara>This &function-t; returns current &step; level.
  </simpara></listitem></varlistentry>
  <varlistentry id="prompt-new-package"><term>&prompt-new-package;</term>
   <listitem><simpara>This &function-t; returns &package-var; or &nil;
     if the current package is the same as it was initially.
  </simpara></listitem></varlistentry>
  <varlistentry id="package-shortest-name"><term>&package-shortest-name;</term>
   <listitem><simpara>This &function-t; takes one argument, a
     &package-t;, and returns its shortest name or nickname.
  </simpara></listitem></varlistentry>
  <varlistentry id="command-index"><term>&command-index;</term>
   <listitem><simpara>contains the current prompt number;
     it is your responsibility to increment it
     (this variable is bound to 0 before saving the &mem-image;).
  </simpara></listitem></varlistentry>
</variablelist></para></section>


<section id="ansi"><title>Maximum ANSI CL compliance</title>

<para>Some &ansi-cl; features are turned off by default for convenience and
 backward compatibility.
 They can be switched on, all at once, by setting the &symbol-macro;
 &ansi; to &t;, or they can be switched on individually.
 Setting &ansi; to &t; implies the following:</para>

<orderedlist>
 <listitem><simpara>Setting &pathprint; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &spacecharprint; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &fixnum-char-ansi; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &count-ansi; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &pathmerge; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &parsename; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &flocont; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &floratcont; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &phasecont; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &loop-ansi; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &pr-empty-arr-ansi; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &pr-unreadable-ansi; to &t;.</simpara></listitem>
 <listitem><simpara>Setting &defun-accept-spelalist; to &nil;.</simpara></listitem>
</orderedlist>

<note><para>If you run &clisp; with the &opt-ansi; switch or set
 the &symbol-macro; &ansi; to &t; and then save &mem-image;,
 then all subsequent invocations of &clisp; with this image
 will be as if with &opt-ansi;
 (regardless whether you actually supply the &opt-ansi; switch).
 You can always set the &symbol-macro; &ansi; to &nil;, or invoke
 &clisp; with the &opt-traditional; switch, reversing the above
 settings, i.e.,</para></note>

<orderedlist>
 <listitem><simpara>Setting &pathprint; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &spacecharprint; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &fixnum-char-ansi; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &count-ansi; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &pathmerge; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &parsename; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &flocont; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &floratcont; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &phasecont; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &loop-ansi; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &pr-empty-arr-ansi; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &pr-unreadable-ansi; to &nil;.</simpara></listitem>
 <listitem><simpara>Setting &defun-accept-spelalist; to &t;.</simpara></listitem>
</orderedlist>

</section>


<section id="macros3"><title>Additional Fancy Macros and Functions</title>

<para>&clisp; comes with some extension macros, mostly defined in the
 file &macros3-lisp; and loaded from the file &init-lisp; during &make;:</para>

<section id="ethe"><title>Macro &ethe;</title>
<para><code>(&ethe; &val-type-r; &form-r;)</code>
 enforces a type check in both interpreted and compiled code.
</para></section>

<section id="letf"><title>Macros &letf; &amp; &letf-star;</title>
<para>These macros are similar to &let; and &let-star;, respectively,
 except that they can bind &place;s, even &place;s with &mul-val;.
 Example:
<programlisting language="lisp">(letf (((values a b) form)) ...)
</programlisting>
is equivalent to
<programlisting language="lisp">(multiple-value-bind (a b) form ...)
</programlisting>
while
<programlisting language="lisp">(letf (((first l) 7)) ...)
</programlisting>
is approximately equivalent to
<programlisting language="lisp">
 (&let-star; ((#:g1 l) (#:g2 (first #:g1)))
   (&unwind-protect; (&progn; (&setf; (first #:g1) 7) ...)
      (&setf; (first #:g1) #:g2)))
</programlisting></para></section>

<section id="memoized"><title>Macro <function>EXT:MEMOIZED</function></title>
<para><code>(<function>EXT:MEMOIZED</function> &form-r;)</code>
 memoizes the &pri-val; of &form-r; from its first evaluation.
</para></section>

<section id="with-collect"><title>Macro &with-collect;</title>
<para>Similar to the &loop;'s
 <ulink role="clhs" url="sec_6-1-3"><literal>COLLECT</literal></ulink>
 construct, except that it is looks more "Lispy" and can appear
 arbitrarily deep.  It defines local macros (with &macrolet;) which
 collect objects given to it into lists, which are then returned as
 &mul-val;.  E.g., <programlisting language="lisp">
(ext:with-collect (c0 c1)
  (dotimes (i 10) (if (oddp i) (c0 i) (c1 i))))
<computeroutput>(1 3 5 7 9)</computeroutput> ;
<computeroutput>(0 2 4 6 8)</computeroutput>
</programlisting> returns two &list-t;s as &mul-val;.</para></section>

<section id="compile-time-value">
 <title>Macro <function>EXT:COMPILE-TIME-VALUE</function></title>
<para>Sometimes one may want to call an expensive function at
 compilation time and write the &pri-val; into the &fasl-file; file,
 thus speeding up loading the &fasl-file; file.
 E.g., let your file <filename>primes.lisp</filename> be
 <programlisting language="lisp">
(defun primes-list (limit)
  "Return the list of all primes smaller than LIMIT."
  ...)
(defvar *all-primes* (compile-time-value (primes-list &most-positive-fixnum;)))
</programlisting>
Then <variablelist>
 <varlistentry><term><code>(&load; "primes.lisp")</code></term>
  <listitem><simpara>will &not-e; call <function>primes-list</function>
    and <varname>*all-primes*</varname> will be &nil;.
 </simpara></listitem></varlistentry>
 <varlistentry><term><code>(&compile-file; "primes.lisp")</code></term>
  <listitem><simpara>will call <function>primes-list</function> (and
    will probably take a long time) and will write the resulting list
    into <code>(&compile-file-pathname; "primes.lisp")</code>
 </simpara></listitem></varlistentry>
 <varlistentry><term><code>(&load; (&compile-file-pathname;
    "primes.lisp"))</code></term>
  <listitem><simpara>will &not-e; call <function>primes-list</function>
    but <varname>*all-primes*</varname> will be the list computed during
    compilation.</simpara></listitem></varlistentry></variablelist></para>
<para>An alternative is to save a &mem-image;, which is faster than &fasl-file;
 file but <link linkend="image-portability">less portable</link>.</para>
</section>

<section id="with-gensyms">
 <title>Macro <function>EXT:WITH-GENSYMS</function></title>
<para>Similar to its namesake from
 <ulink url="http://www.paulgraham.com/">Paul Graham</ulink>'s book
 <ulink url="http://www.paulgraham.com/onlisp.html"><quote>On
  Lisp</quote></ulink>, this macro is useful for writing other macros:
<programlisting language="lisp">
(with-gensyms ("FOO-" bar baz zot) ...)
</programlisting>
expands to
<programlisting language="lisp">
(let ((bar (gensym "FOO-BAR-"))
      (baz (gensym "FOO-BAZ-"))
      (zot (gensym "FOO-ZOT-")))
  ...)
</programlisting>
</para></section>

<section id="remove-plist">
 <title>Function <function>EXT:REMOVE-PLIST</function></title>
<para>Similar to &remove; and &remf;, this function removes some
 properties from a &plist;.  It is non-destructive and thus can be
 used on &rest-amp; arguments to remove some keyword parameters, e.g.,
<programlisting language="lisp">
(defmacro with-foo ((&key-amp; foo1 foo2) &body-amp; body)
  `(... ,foo1 ... ,foo2 ... ,@body))
(defmacro with-foo-bar ((&rest-amp; opts &key-amp; bar1 bar2
                         &allow-other-keys-amp;)
                        &body-amp; body)
  `(with-foo (,@(remove-plist opts :bar1 :bar2)
     ... ,bar1 ... ,bar2 ... ,@body)))
(defun foo-bar ()
  (with-foo-bar (:bar1 1 :foo2 2) ...))
</programlisting>
here <function>WITH-FOO</function> does not receive the
<literal>:BAR1 1</literal> argument from <function>FOO-BAR</function>.
</para></section>

<section id="html-http-output">
 <title>Macros <function>EXT:WITH-HTML-OUTPUT</function> and
  <function>EXT:WITH-HTTP-OUTPUT</function></title>
<para>Defined in &inspect-lisp;, these macros are useful
 for the rudimentary &http; server defined there.</para></section>

<section id="open-http"><title>Function &open-http; and
  macro <function>EXT:WITH-HTTP-INPUT</function></title>
<para>Defined in
 <link linkend="clhs-lisp"><filename>clhs.lisp</filename></link>,
 they allow downloading data over the Internet using the &http; protocol.
 <code>(&open-http; url &key-amp; &if-does-not-exist; :LOG)</code> opens
 a &sock; connection to the <replaceable>url</replaceable> host,
 sends the <command>GET</command> request,
 and returns two values: the &socket-stream; and content length.
<code>(EXT:WITH-HTTP-INPUT (&var-r; url) &body-amp; body)</code> binds &var-r;
to the &socket-stream; returned by &open-http; and executes the &body-r;.
<code>(EXT:WITH-HTTP-INPUT ((&var-r; &cont-r;) url) &body-amp; body)</code>
additionally binds &cont-r; to the content length.</para>
<para>&open-http; will check &http-proxy; on startup and parse the &env-var;
 <envar>HTTP_PROXY</envar> if &http-proxy; is &nil;.</para>
<para>The <constant>:LOG</constant> argument binds &http-log-stream;.</para>
</section>

<section id="http-log-stream"><title>Variable &http-log-stream;</title>
 <para>Function &open-http; logs its actions to &http-log-stream;
  which is initially set to &terminal-io-var;.</para></section>

<section id="browse-url"><title>Function &browse-url;</title>
 <para>Function <code>(&browse-url; url &key-amp; &browser-k; &out-k;)</code>
  calls a browser on the URL. <replaceable>browser</replaceable>
  (defaults to &browser;) should be a valid keyword in the &browsers; &alist;.
  &out-k; specifies the stream where the progress messages are printed
  (defaults to &standard-output-var;).
</para></section>

<section id="http-proxy"><title>Variable &http-proxy;</title>
<para>If you are behind a proxy server, you will need to set &http-proxy; to
 a &list-t; <literal role="data">(name:password host port)</literal>.
 By default, the &env-var; <envar>http_proxy</envar> is used, the
 expected format is <literal role="data">"name:password@host:port"</literal>.
 If no <literal role="data">#\@</literal> is present,
 &name-r; and &pass-r; are &nil;.
 If no <literal role="data">#\:</literal> is present,
 &pass-r; (or &port-r;) is &nil;.</para>
<para>Use function <code>(EXT:HTTP-PROXY &optional-amp; (&string-t;
  (&getenv; "http_proxy")))</code> to reset
  &http-proxy;.</para></section>

<section id="canonicalize"><title>Function &canonicalize;</title>
<para>If you want to canonicalize a &value-r; before further processing it, you
 can pass it to &canonicalize; together with a &sequence-t; of &function-t;s:
 <code>(&canonicalize; &value-r; <replaceable>functions</replaceable>
  &key-amp; (test '&eql;) (max-iter 1024))</code> will call &func-r;s on
 &value-r; until it stabilizes under <replaceable>test</replaceable>
 (which should be a valid &hash-table-test;) and return the stabilized
 value and the number of iterations the stabilization required.</para>
<para>E.g., &new-clx; uses it together with
 <firstterm><varname>XLIB:*CANONICALIZE-ENCODING*</varname></firstterm>
 to fix the broken encoding names returned by the &X; (e.g., convert
 <literal>"iso8859-1"</literal> to <literal>"ISO-8859-1"</literal>)
 before passing them over to &make-encoding;. If you encounter an &encoding;
 &error-t; in &new-clx;, you can augment this variable to avoid it.
</para></section>

</section>

<section id="customize"><title>Customizing &clisp; behavior</title>

<para>The user-customizable variables and functions are located in the
 package &custom-pac; and thus can be listed using
 <code>(&apropos; "" "CUSTOM")</code>:
 <simplelist type="horiz" columns="2">
  <member>&ansi;</member>
  <member><varname>CUSTOM:*APPLYHOOK*</varname></member>
  <member>&apropos-do-more;</member>
  <member>&apropos-matcher;</member>
  <member><varname>CUSTOM:*BREAK-ON-WARNINGS*</varname></member>
  <member>&browser;</member>
  <member>&browsers;</member>
  <member>&clhs-root;</member>
  <member>&clhs-root-default;</member>
  <member>&fixnum-char-ansi;</member>
  <member>&compile-warn;</member>
  <member>&compiled-types;</member>
  <member>&curr-lang;</member>
  <member>&def-file-enc;</member>
  <member>&default-float-format;</member>
  <member>&default-tz;</member>
  <member><varname>CUSTOM:*DEFTYPE-DEPTH-LIMIT*</varname></member>
  <member>&defun-accept-spelalist;</member>
  <member>&dev-prefix;</member>
  <member>&editor;</member>
  <member><link linkend="make-hash"><varname>CUSTOM:*EQ-HASHFUNCTION*</varname></link></member>
  <member><link linkend="make-hash"><varname>CUSTOM:*EQL-HASHFUNCTION*</varname></link></member>
  <member><link linkend="make-hash"><varname>CUSTOM:*EQUAL-HASHFUNCTION*</varname></link></member>
  <member><varname>CUSTOM:*ERROR-HANDLER*</varname></member>
  <member><varname>CUSTOM:*EVALHOOK*</varname></member>
  <member>&fill-indent-sexp;</member>
  <member>&fini-hooks;</member>
  <member>&flocont;</member>
  <member>&floratcont;</member>
  <member>&foreign-enc;</member>
  <member>&http-log-stream;</member>
  <member>&http-proxy;</member>
  <member>&impnotes-root;</member>
  <member>&impnotes-root-default;</member>
  <member>&init-hooks;</member>
  <member><link linkend="inspect"><varname>CUSTOM:*INSPECT-BROWSER*</varname></link></member>
  <member><link linkend="inspect"><varname>CUSTOM:*INSPECT-FRONTEND*</varname></link></member>
  <member><link linkend="inspect"><varname>CUSTOM:*INSPECT-LENGTH*</varname></link></member>
  <member><link linkend="inspect"><varname>CUSTOM:*INSPECT-PRINT-LENGTH*</varname></link></member>
  <member><link linkend="inspect"><varname>CUSTOM:*INSPECT-PRINT-LEVEL*</varname></link></member>
  <member><link linkend="inspect"><varname>CUSTOM:*INSPECT-PRINT-LINES*</varname></link></member>
  <member>&libdir;</member>
  <member>&load-comp;</member>
  <member>&load-echo;</member>
  <member>&load-lpt-db;</member>
  <member>&load-obs;</member>
  <member>&load-paths;</member>
  <member>&loop-ansi;</member>
  <member>&pathmerge;</member>
  <member>&misc-enc;</member>
  <member>&module-providers;</member>
  <member><varname>CUSTOM:*PACKAGE-TASKS-TREAT-SPECIALLY*</varname></member>
  <member>&parsename;</member>
  <member>&parsedot;</member>
  <member>&path-enc;</member>
  <member>&phasecont;</member>
  <member>&ppr-first-newline;</member>
  <member>&pr-closure;</member>
  <member>&pr-empty-arr-ansi;</member>
  <member>&pr-indent;</member>
  <member>&pr-sym-pack-prefix;</member>
  <member>&pathprint;</member>
  <member><varname>CUSTOM:*PRINT-PRETTY-FILL*</varname></member>
  <member>&pr-rpars;</member>
  <member>&spacecharprint;</member>
  <member>&pr-unreadable-ansi;</member>
  <member>&prompt-body;</member>
  <member>&prompt-break;</member>
  <member>&prompt-finish;</member>
  <member>&prompt-start;</member>
  <member>&prompt-step;</member>
  <member>&reopen;</member>
  <member>&err-pr-bt;</member>
  <member>&savemem-verbose;</member>
  <member>&count-ansi;</member>
  <member>&source-types;</member>
  <member>&suppress-check-redef;</member>
  <member>&suppress-similar-const-redef;</member>
  <member>&sys-pack-list;</member>
  <member>&term-enc;</member>
  <member>&trace-indent;</member>
  <member>&user-commands;</member>
  <member>&user-libdir;</member>
  <member><varname>CUSTOM:*USER-MAIL-ADDRESS*</varname></member>
  <member>&warn-fpc;</member>
  <member>&warn-on-hashtable-needing-rehash-after-gc;</member>
  <member><varname>CUSTOM:*WITH-HTML-OUTPUT-DOCTYPE*</varname></member>
</simplelist></para>
<note><title>Note</title><para>Some of these variables are
  platform-specific.</para></note>

<para>You should set these variables (and do whatever other
 customization you see fit) in the file &config-lisp; in the build
 directory before building &clisp;.
 Alternatively, after building &clisp;, or if you are using a binary
 distribution of &clisp;, you can modify &config-lisp;, compile and load
 it, and then save the &mem-image;.
 Finally, you can create an &RC-file; which is loaded whenever &clisp;
 is started.</para>

</section>

<section id="code-walk"><title>Code Walker</title>

<para>You can use function &expand-form; to expand all the macros,
 &symbol-macro;s, etc, in a single form:
<programlisting language="lisp">
(&expand-form; '(macrolet ((bar (x) `(print ,x)))
                    (macrolet ((baz (x) `(bar ,x)))
                      (symbol-macrolet ((z 3))
                        (baz z)))))
<computeroutput>(locally (print 3))</computeroutput> <lineannotation>the expansion</lineannotation>
<computeroutput>&t;</computeroutput> <lineannotation>indicator: some expansion has actually been done</lineannotation>
</programlisting></para>

<para>This is sometimes called a <quote>code walker</quote>,
 except that a code walker would probably leave the &macrolet; and
 &symbol-macrolet; forms intact and just do the expansion.</para>

<warning><para>Function &expand-form; is the exported part of the
  &clisp; interpreter (AKA &eval;), so it expands forms by assuming the
  &eval-when; situation <constant>:EXECUTE</constant> and is therefore
  unsuitable for forms that may later be passed to the compiler:
<programlisting language="lisp">
(&expand-form; '(&eval-when; (:COMPILE-TOPLEVEL) (foo)))
<computeroutput>&nil;</computeroutput> ;
<computeroutput>&t;</computeroutput>
(&expand-form; '(&eval-when; (:LOAD-TOPLEVEL) (foo)))
<computeroutput>&nil;</computeroutput> ;
<computeroutput>&t;</computeroutput>
</programlisting></para></warning>
</section>

</chapter>

<chapter id="ext-platform"><title>Platform Specific Extensions</title>

<!-- #if defined(SCREEN) -->

<section id="screen"><title>Random Screen Access</title>
<subtitle>&unix-w32-only;</subtitle>

<variablelist>
 <varlistentry><term><code>(<function>SCREEN:MAKE-WINDOW</function>)</code></term>
  <listitem><simpara>returns a <type>WINDOW-STREAM</type>.
    As long as this stream is open, the terminal is in cbreak/noecho mode.
    &terminal-io-var; should not be used for input or output during this
    time.  (Use &with-kbd; and &kbd-in; instead.)
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:WITH-WINDOW</function> .
    &body-r;)</code></term>
  <listitem><simpara>binds
    <firstterm>&scr-win;<indexterm id="scr-win" significance="preferred">
      <primary><varname>*WINDOW*</varname>
    </primary></indexterm></firstterm>
    to a <type>WINDOW-STREAM</type> and executes &body-r;.
    The stream is guaranteed to be closed when the body is left.
    During its execution, &terminal-io-var; should not be used, as above.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:WINDOW-SIZE</function>
    &ws-r;)</code></term>
  <listitem><simpara>returns the window's size, as two values:
   height (= y&sub-max;+1) and width (= x&sub-max;+1).
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:WINDOW-CURSOR-POSITION</function>
    &ws-r;)</code></term>
  <listitem><simpara>returns the position of the cursor in the window,
   as two values: line (&ge;0, &le;y&sub-max;, 0 means top), column
   (&ge;0, &le;x&sub-max;, 0 means left margin).
 </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:SET-WINDOW-CURSOR-POSITION</function>
    &ws-r; &line-r; &col-r;)</code></term>
  <listitem><simpara>sets the position of the cursor in the window.
  </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:CLEAR-WINDOW</function>
    &ws-r;)</code></term>
  <listitem><simpara>clears the window's contents and puts the cursor
    in the upper left corner.</simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:CLEAR-WINDOW-TO-EOT</function>
    &ws-r;)</code></term>
  <listitem><simpara>clears the window's contents from the cursor
    position to the end of window.</simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:CLEAR-WINDOW-TO-EOL</function>
    &ws-r;)</code></term>
  <listitem><simpara>clears the window's contents from the cursor
    position to the end of line.</simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:DELETE-WINDOW-LINE</function>
    &ws-r;)</code></term>
  <listitem><simpara>removes the cursor's line, moves the lines below
    it up by one line and clears the window's last line.
 </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:INSERT-WINDOW-LINE</function>
    &ws-r;)</code></term>
  <listitem><simpara>inserts a line at the cursor's line, moving the
    lines below it down by one line.</simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:HIGHLIGHT-ON</function>
    &ws-r;)</code></term>
  <listitem><simpara>switches highlighted output on.
 </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:HIGHLIGHT-OFF</function>
    &ws-r;)</code></term>
  <listitem><simpara>switches highlighted output off.
 </simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:WINDOW-CURSOR-ON</function>
    &ws-r;)</code></term>
  <listitem><simpara>makes the cursor visible, a cursor block in most
    implementations.</simpara></listitem></varlistentry>
 <varlistentry><term><code>(<function>SCREEN:WINDOW-CURSOR-OFF</function>
    &ws-r;)</code></term>
  <listitem><simpara>makes the cursor invisible, in implementations
    where this is possible.</simpara></listitem></varlistentry>
</variablelist>
</section>
<!-- #endif -->

<!-- #if defined(UNIX) || defined(WIN32_NATIVE) -->
<section id="modules"><title>External Modules</title>
<subtitle>&unix-w32-only;</subtitle>

<note id="mod-win32"><title>Modules on &win32;</title>
 <para>Everything described in the section will work verbatim on &win32;
  when using &cygwin; or &mingw;, <emphasis>except</emphasis> for one
  thing - you will need to replace the <filename>run</filename>
  extension in &lisp-run; with the &win32; executable
  extension <filename>exe</filename>.</para>
 <para>For historical reasons, all examples appear to assume &unix; and
  use the <filename>run</filename> file type (<quote>extension</quote>)
  for the &clisp; &rt;.
  This does &not-e; mean that they will not work on &win32;.</para>
</note>

<section id="mod-overview"><title>Overview</title>

<para><emphasis>External modules</emphasis> are a mechanism to add
 extensions (written in &c-lang;, for example) to &clisp;.
 Extending &clisp; using an external module requires creating a &modset;
 and adding it to an existing &linkset; using &clisp-link; to prodice a
 new &linkset; which contains the extension. </para>

<simplesect id="modset"><title>Module Set</title>
<para>A <firstterm>module<indexterm id="module" significance="preferred">
   <primary>module</primary></indexterm></firstterm> is a piece of code
 (&c-lang; or Lisp) which defines extra (non-core) Lisp objects, symbols
 and functions. Together with &link-sh;, which describes how to add the
 module to an existing &clisp;, it comprises a &modset;.</para>
<para>More formally,
 <firstterm>&modset;<indexterm id="modseti" significance="preferred">
   <primary>module set</primary></indexterm></firstterm>
 is a directory containing:
<variablelist><varlistentry><term>&link-sh;</term>
  <listitem><simpara>some &sh; commands, which prepare the directory
    for linking, and set some &env-var;s, see <xref linkend="mod-vars"/>
 </simpara></listitem></varlistentry>
 <varlistentry><term>all other files that define the module functionality</term>
  <listitem><simpara>needed by &link-sh;</simpara></listitem></varlistentry>
</variablelist></para>
<para>In &link-sh; the &modset; directory is referred to
 as <varname>$modulename/</varname>.</para>
<para>A module <firstterm>name<indexterm id="module-name">
 <primary>module</primary><secondary>name</secondary></indexterm></firstterm>
 must consist of the characters <filename>A</filename>-<filename>Z</filename>,
 <filename>a</filename>-<filename>z</filename>, <filename>_</filename>,
 <filename>0</filename>-<filename>9</filename>.</para>
<para>The module name <quote>clisp</quote> is reserved.</para>
</simplesect>

<simplesect id="linkset"><title>Linking Set</title>
<para>A <firstterm>&linkset;<indexterm id="linkseti" significance="preferred">
   <primary>linking set</primary></indexterm></firstterm>
 is a collection of files (&rt;, &mem-image; &amp;c) which allows
 performing two major tasks:
 <orderedlist><listitem><para>Running &clisp;: to run a &clisp;
    contained in some &linkset; &dir-r;, call<screen>
&sh-prompt; &dir-r;/lisp.run &opt-M; &dir-r;/lispinit.mem</screen>
 or <screen>&sh-prompt; &clisp-cmd; &opt-K; &dir-r;</screen>
 (recommended, since it also passes
 <option><olink targetdoc="man" targetptr="opt-libdir">-B</olink></option>
 to the &rt;).</para></listitem>
  <listitem><simpara>Adding a &modset; to create a new &linkset; which
    will contain the module functionality.</simpara></listitem></orderedlist>
 The &clisp; build directory contains three &linkset;s in
 directories <command>boot</command>, &base;, and &full;, and a &clisp;
 installation normally contains two &linkset;s: &base;, and &full;</para>
<para>More formally, a &linkset; is a directory containing at least
  these files:<variablelist>
<varlistentry><term>&lisp-run;</term>
 <listitem><simpara>the executable &rt;</simpara></listitem></varlistentry>
<varlistentry><term>&lispinit;</term>
 <listitem><simpara>the &mem-image;</simpara></listitem></varlistentry>
<varlistentry><term><filename>modules.h</filename></term>
 <listitem><simpara>the list of modules contained in this &linkset;
</simpara></listitem></varlistentry>
<varlistentry><term><filename>modules.o</filename></term>
 <listitem><simpara>the compiled list of modules contained in this &linkset;
</simpara></listitem></varlistentry>
<varlistentry id="makevars"><term><filename>makevars</filename></term>
 <listitem><para>some &sh; commands, setting the variables
   <variablelist>&varlist-table;<varlistentry><term><envar>CC</envar></term>
     <listitem><simpara>the &c-lang; compiler
    </simpara></listitem></varlistentry>
    <varlistentry><term><envar>CPPFLAGS</envar></term>
     <listitem><simpara>flags for the &c-lang; compiler, when preprocessing
       or compiling</simpara></listitem></varlistentry>
    <varlistentry><term><envar>CFLAGS</envar></term>
     <listitem><simpara>flags for the &c-lang; compiler, when compiling or
       linking</simpara></listitem></varlistentry>
    <varlistentry><term><envar>CLFLAGS</envar></term>
     <listitem><simpara>flags for the &c-lang; compiler, when linking
    </simpara></listitem></varlistentry>
    <varlistentry><term><envar>LIBS</envar></term>
     <listitem><simpara>libraries to use when linking (either present in
       the &linkset; directory, or system-wide)
    </simpara></listitem></varlistentry>
    <varlistentry><term><envar>X_LIBS</envar></term>
     <listitem><simpara>additional &X; libraries to use
    </simpara></listitem></varlistentry>
    <varlistentry><term><envar>RANLIB</envar></term>
     <listitem><simpara>the ranlib command
    </simpara></listitem></varlistentry>
    <varlistentry><term><envar>FILES</envar></term>
     <listitem><simpara>the list of files needed when linking
    </simpara></listitem></varlistentry>
</variablelist></para></listitem></varlistentry>
<varlistentry><term>all the <envar>FILES</envar></term>
 <listitem><simpara>listed in <filename>makevars</filename>
</simpara></listitem></varlistentry>
</variablelist></para>
</simplesect>

<simplesect id="clisp-link"><title>Manipulating &modset;s and &linkset;s</title>
<para>Use &clisp-link; to create and install &modset;s
 and add them to &linkset;s.</para>
<para>See also <xref linkend="mod-set-example"/>.</para>
</simplesect>

<simplesect id="mod-vars"><title>Module set variables</title>
<para>The following variables should be defined in &link-sh;.</para>
<variablelist>
<varlistentry><term><envar>NEW_FILES</envar></term>
 <listitem><simpara>the space-separated list of object files that
  belong to the &modset; and will belong to every new &linkset; linked
  with this &modset;.</simpara></listitem></varlistentry>
<varlistentry><term><envar>NEW_LIBS</envar></term>
 <listitem><simpara>the space-separated list of object files, libraries or
  &c-lang; compiler switches that need to be passed to the &c-lang;
  compiler when linking the &lisp-run; belonging to a new &linkset;.
 </simpara></listitem></varlistentry>
<varlistentry><term><envar>NEW_MODULES</envar></term>
 <listitem><simpara>the space-separated list of the module names
  belonging to the &modset;.  Normally, every &c-file; file in the
  &modset; defines a module of its own.  The module name is usually
  derived from the file name.</simpara></listitem></varlistentry>
<varlistentry id="mod-load"><term>&mod-load;</term>
 <listitem><simpara>the space-separated list of Lisp files to load
  before building the &lispinit; belonging to a new &linkset;.
 </simpara></listitem></varlistentry>
<varlistentry id="mod-preload"><term>&mod-preload; (optional)</term>
 <listitem><simpara>the space-separated list of Lisp files to load
   into an intermediate &lispinit; file, before building the &lispinit;
   belonging to a new &linkset;.
   This variable is usually used to <link linkend="make-pack">create</link>
   (or <link linkend="pack-lock">unlock</link>) the Lisp &package-t;s which
   must be present when the new &c-file; files are initialized.
   E.g., the &def-call-in; functions must reside in already defined packages;
   see <xref linkend="ex-call-in"/>.  You can find a live example in
   <filename role="clisp-cvs">modules/syscalls/preload.lisp</filename>
   and <filename role="clisp-cvs">modules/syscalls/link.sh.in</filename>.
  </simpara>
  <warning><simpara>If you are unlocking a package, you must also
    &delete; it from &sys-pack-list; (see <xref linkend="image"/>) here
    and re-add it to &sys-pack-list; in one of the &mod-load; files.
    See, e.g., <filename role="clisp-cvs">modules/i18n/preload.lisp</filename>
    and <filename role="clisp-cvs">modules/i18n/link.sh.in</filename>.
</simpara></warning></listitem></varlistentry>
</variablelist></simplesect>

</section>

<section id="modinit"><title>Module initialization</title>

<para>Each module has two initialization functions:
 <variablelist><varlistentry><term>void
    <function>module__&name-r;__init_function_1</function>
    (struct module_t* module)</term>
<listitem><simpara>called only <emphasis>once</emphasis> when &clisp;
  discovers while loading a &mem-image; that there is a module present
  in the executable (&lisp-run;) which was not present at the time the
  image was saved.  It can be used to create Lisp objects,
  e.g. functions or keywords, and is indeed used for that purpose by
  &modprep;.</simpara>
 <simpara>You do &not-e; have to define this function yourself;
  &modprep; and &ffi-pac; will do that for you.</simpara>
 <simpara>If you use &ffi-pac;, <code>(&c-lines; :init-once ...)</code>
  will add code to this function.</simpara>
 <warning><simpara>The &package-t;s must already exist and be unlocked,
   cf. &mod-preload;.</simpara></warning>
 <warning><simpara>If you are using &modprep; &and-e; defining your
   own <quote>init-once</quote> function, it must call the
   <function>module__&name-r;__init_function_1__modprep</function>
   function!</simpara></warning></listitem></varlistentry>
<varlistentry><term>void <function>module__&name-r;__init_function_2</function>
  (struct module_t* module)</term>
<listitem><simpara>called <emphasis>every time</emphasis> &clisp; starts.
  It can be used to bind names to foreign addresses, since the address
  will be different in each invocation of &clisp;, and is indeed used
  for that purpose by &ffi-pac; (e.g., by &def-call-out;).
  It can also be used to set parameters of the libraries to which the
  module interfaces, e.g., the &pcre-mod; module
  sets <varname>pcre_malloc</varname> and <varname>pcre_free</varname>.
 </simpara><simpara>You do &not-e; have to define this function yourself;
  &modprep; and &ffi-pac; will do that for you.</simpara>
 <simpara>If you use &ffi-pac;, <code>(&c-lines; :init-always ...)</code>
  will add code to this function.</simpara>
</listitem></varlistentry></variablelist>
&name-r; is the <link linkend="mod-overview">module name</link>.</para>
<para>See also <xref linkend="custom-init-fini"/>.</para>
</section>

<section id="modfini"><title>Module finalization</title>

<para>Each module has a finalization function
<variablelist><varlistentry><term>void
   <function>module__&name-r;__fini_function</function>
   (struct module_t* module)</term>
<listitem><simpara>called before exiting &clisp;.</simpara>
 <simpara>You do &not-e; have to define this function yourself;
  &modprep; and &ffi-pac; will do that for you.</simpara>
 <simpara>If you use &ffi-pac;, <code>(&c-lines; :fini ...)</code> will
  add code to this function.</simpara>
</listitem></varlistentry></variablelist>
&name-r; is the <link linkend="mod-overview">module name</link>.</para>
<para>See also <xref linkend="custom-init-fini"/>.</para>
</section>

<section id="modinfo"><title>Function &modinfo;</title>

<para>Function <code>(&modinfo; &optional-amp; &name-r;
  <replaceable>verbose</replaceable>)</code> allows one to inquire
 about what modules are available in the currently running image.
 When called without arguments, it returns the list of module names,
 starting with <quote>clisp</quote>.  When &name-r; is supplied and
 names a module, 3 values are returned - &name-r;,
 <replaceable>subr-count</replaceable>,
 <replaceable>object-count</replaceable>.
 When <replaceable>verbose</replaceable> is non-&nil;, the full list of
 module lisp function names written in &c-lang; (<type>Subr</type>s) and
 the full list of internal lisp objects available in &c-lang; code
 are additionally returned for the total of 5 values.</para>

<para>When &name-r; is <constant>:FFI</constant>, returns the list of
 shared libraries opened using &library-k;.
 When <replaceable>verbose</replaceable> is non-&nil;, return the
 &alist; of DLL names and all foreign objects associated with it.</para>
</section>

<section id="mod-dynload"><title>Dynamic module loading</title>
<subtitle>&dynmod-only;</subtitle>

<note><para>Dynamic loading does not work on all operating systems
  (&dlopen; or equivalent is required).</para></note>
<note><para>You will probably never need to call the function &mod-dynload;
  explicitly (this is why it is in &sys-pac; and not in &ext-pac;).
  You should install your module with
  <screen>&sh-prompt; &clisp-link; &opt-install; &name-r;</screen>
  and load it with <code>(&require-my; &name-r;).</code></para></note>

<para>Function <code>(&mod-dynload; &filename-r; ({&name-r;}+))</code>
 loads a shared object file or library containing a number of named
 external &clisp; modules.
 <note><simpara>This facility &cannot-e; be used to
   access arbitrary shared libraries.  To do that, use the &library-k;
   argument to &def-call-out; and &def-c-var; instead.</simpara></note>
</para>

<para>External modules for &clisp; are shared objects
 (dynamic libraries) that contain the
 <literal>module__&name-r;__subr_tab</literal> variable, among others.
 This serves to register external functions which operate on Lisp-level
 structures with &clisp;.</para>

<para>To use &dlopen; with modules, you should add
 <ulink url="http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html"><option>-fPIC</option></ulink> to the module's compilation options.
 Something like
 <screen>&sh-prompt; cc -shared -o &name-r;.so &name-r;.o</screen>
 may be needed to produce the shared object file.</para>

</section>

<section id="mod-set-example"><title>Example</title>
<example id="mod-set-ex-bindings">
 <title>Create a &modset; with &glibc; bindings</title>
<para>To link in the &ffi-pac; bindings for the &gnu;/&linux; operating
 system, the following steps are needed.  (Step 1 and step 2 need not be
 executed in this order.)</para>

<procedure><step><title>Create a new &modset;</title>
<screen>&sh-prompt; &clisp-link; create linux /&path-r;/bindings/linux.c</screen></step>

<step><title>Modify the newly created
  <filename>linux/&link-sh;</filename></title>
 <substeps><step><title>add <option>-lm</option> to the libraries</title>
   <para>replace <screen>NEW_LIBS="$file_list"</screen>
    with <screen>NEW_LIBS="$file_list -lm"</screen></para></step>
  <step><title>load <filename>linux.fas</filename> before saving the
    &mem-image;</title><para>replace <screen>TO_LOAD=''</screen> with
    <screen>TO_LOAD='/&path-r;/bindings/linux.fas'</screen></para></step>
</substeps></step>

<step><title>Compile <filename>linux.lisp</filename>, creating
  <filename>linux.c</filename></title>
<screen>&sh-prompt; &clisp-cmd; &opt-c; /&path-r;/bindings/linux.lisp</screen></step>

<step><title>Create a new &linkset;</title>
<screen>&sh-prompt; &clisp-link; add base base+linux linux</screen></step>

<step><title>Run and try it</title>
<screen>&sh-prompt; base+linux/lisp.run &opt-M; base+linux/lispinit.mem &opt-x; '(linux:stat "/tmp")'</screen></step>
</procedure>
</example>
</section>

<section id="module-tools"><title>Module tools</title>

<para>There are some tools to facilitate easy module writing.</para>

<section id="modprep"><title>Modprep</title>
<para>If your module is written in &c-lang;, you can pre-process your
 sources with &modprep; in the &clisp; distribution and define lisp
 functions with the <function>DEFUN</function> macro:
 <programlisting language="C">
DEFUN(MY-PACKAGE:MY-FUNCTION-NAME, arg1 arg2 &key-amp; FOO BAR) {
  if (!boundp(STACK_0)) STACK_0 = fixnum(0); /* BAR */
  if (!boundp(STACK_1)) STACK_1 = fixnum(1); /* FOO */
  pushSTACK(`MY-PACKAGE::SOME-SYMBOL`); /* create a symbol in the package */
  pushSTACK(`#(:THIS :IS :A :VECTOR)`); /* some vector, created once */
  pushSTACK(``MY-PACKAGE::MY-FUNCTION-NAME``); /* double `` means FUNCTION */
  VALUES1(listof(7)); /* cons up a new list and clean up the STACK */
}</programlisting>
Then <code>(MY-PACKAGE:MY-FUNCTION-NAME 'A 12 :FOO T)</code> will
 return <returnvalue>(A 12 T 0 MY-PACKAGE::SOME-SYMBOL #(:THIS
  :IS :A :VECTOR) #&lt;ADD-ON-SYSTEM-FUNCTION
  MY-PACKAGE:MY-FUNCTION-NAME&gt;)</returnvalue>
(assuming you &export;ed <literal>MY-FUNCTION-NAME</literal> from
 <quote role="package">MY-PACKAGE</quote>).</para>

<para>Note that the arguments are passed on the &STACK; (last argument
 being the top) which has to be cleaned up before exit.</para>

<para>Another useful macros are:
 <variablelist><varlistentry><term><function>DEFVAR</function></term>
   <listitem><simpara>create a GC-visible private object
  </simpara></listitem></varlistentry>
  <varlistentry><term><function>DEFFLAGSET</function></term>
   <listitem><simpara>define a &c-lang; function which will remove
     several flag arguments from the &STACK; and return the combined flag
     value</simpara></listitem></varlistentry>
  <varlistentry><term><function>DEFCHECKER</function></term>
   <listitem><simpara>define a map from &cpp; constants to lisp symbols and
     functions that map between them, checking that the argument is appropriate
  </simpara></listitem></varlistentry>
</variablelist></para>

<para>See <filename role="clisp-cvs">modules/syscalls/calls.c</filename>
 and other included modules for more examples and file &modprep; for full
 documentation.</para>
<warning><para>If you manipulate Lisp objects, you need to watch out for
  <link linkend="gc-safety">GC-safety</link>.</para></warning>
</section>

<section id="clisp-h"><title>clisp.h</title>

<para>If your module is written in &c-lang;, you will probably want
 to <literal>#include "clisp.h"</literal> to access &clisp; objects.
 You will certainly need to read &clisp-h; and some code in
 <link linkend="included-modules">included modules</link>, but here are
 some important hints that you will need to keep in mind:
<itemizedlist>
 <listitem><simpara>Lisp objects have type &object-t;.</simpara></listitem>
 <listitem><simpara>Variables of this type are invalidated by
   <link linkend="gc-safety">lisp memory allocation</link>
   (<function>allocate_*()</function> functions) - but &not-e; &c-lang;
   allocations (&malloc; et al) - and must be saved on the &STACK; using &cpp;
   macros <function>pushSTACK()</function>, <function>popSTACK()</function>
   and <function>skipSTACK()</function>.</simpara></listitem>
 <listitem><simpara>Access object slots using the
   appropriate <function>TheFoo()</function> macro, e.g.,
   <function>TheCons(my_cons)-&gt;Car</function>, but first check the
   type with <function>consp()</function>.</simpara></listitem>
 <listitem><simpara>Arguments are passed on the &STACK;, as illustrated
   in the <link linkend="modprep">above example</link>.</simpara></listitem>
 <listitem><simpara>Wrap your system calls in
   <literal>begin_system_call()</literal>/<literal>end_system_call()</literal>
   pairs.  These macros, defined in &clisp-h;, save and restore
   registers used by &clisp; which could be clobbered by a system call.
  </simpara><simpara>If the system call could block (e.g., &read-U;)
   you need to use <literal>begin_blocking_system_call()</literal> and
   <literal>end_blocking_system_call()</literal> instead. This will
   allow other threads to run while yours is inside the system call.
   This means that &gc;ion could happen while you are inside this system
   call and, thus, that all objects of type &object-t; are
   invalidated by the call. See also <xref linkend="gc-safety"/> and
   <xref linkend="gc-mt"/>.</simpara></listitem></itemizedlist>
</para>

</section>

<section id="exporting"><title>Exporting</title>
<para>If your module uses &ffi-pac; to interface to a &c-lang; library,
 you might want to make your module package &case-sensitive-k; and use
 &exporting-lisp; in the &clisp; distribution to make &ffi-pac; forms
 and &defun;, &defmacro; at al export the symbols they define.
 See <filename role="clisp-cvs">modules/netica/</filename>,
 <filename role="clisp-cvs">modules/matlab/</filename> and
 <filename role="clisp-cvs">modules/bindings/</filename> for examples.</para>
</section>

</section>

<section id="mod-ffi-vs-c"><title>Trade-offs: &ffi-pac; vs. &c-lang;
  modules</title>
<para>When deciding how to write a module: whether to use &ffi-pac; or
 to stick with &c-lang; and &modprep;, one has to take into account
 several issues: <variablelist>
<varlistentry><term>Speed: &c-lang; wins</term>
 <listitem><para>&ffi-pac; has a noticeable overhead:
   compare <function>RAWSOCK:HTONS</function> (defined
   in <filename role="clisp-cvs">modules/rawsock/rawsock.c</filename>)
   with <programlisting language="lisp">
(&def-call-out; htons (&name-k; "htons") (&library-k; :default)
  (&arguments-k; (s ffi:short)) (&ret-type-k; ffi:short) (&lang-k; :stdc))
</programlisting> and observe that <function>RAWSOCK:HTONS</function> is
   almost 3 times as fast (this really does compare the &ffi-pac;
   overhead to the normal lisp function call because
   <function role="unix">htons</function> is computationally trivial).
   This difference will matter only if you call a simple function very
   many times, in which case it would make sense to put the loop itself
   into &c-lang;.</para></listitem></varlistentry>
<varlistentry><term>Portability: &c-lang; wins</term>
 <listitem><orderedlist><listitem><simpara>&ffi-pac; is &not-e; as widely
     ported as &clisp;, so it is possible that you will face a platform
     where &clisp; runs but &ffi-pac; is not present.</simpara></listitem>
   <listitem><simpara>It is much easier to handle portability in
     &c-lang;: observe the alternative implementations
     of <function role="unix">htonl</function> et al in
     <filename role="clisp-cvs">modules/rawsock/rawsock.c</filename>.
   </simpara></listitem>
   <listitem><simpara>Certain &c-lang; structures have different
     layout on different platforms, and functions may take 64-bit
     arguments on some platforms and 32-bit arguments on others; so the
     &ffi-pac; code has to track those differences, while &c-lang; will
     mostly take care of these things for you.</simpara></listitem>
</orderedlist></listitem></varlistentry>
<varlistentry><term>Code size: &ffi-pac; wins</term>
 <listitem><simpara>You need to type much fewer characters with &ffi-pac;,
   and, if you use the &library-k; argument to &def-call-out; and
   &def-c-var;, you do not need to leave your &clisp; session to try
   out your code.  This is a huge advantage for rapid prototyping.
</simpara></listitem></varlistentry>
<varlistentry><term>UI: &c-lang; wins</term>
 <listitem><simpara>To produce a nice lispy UI (using &optional-amp; and
   &key-amp;word arguments etc), you will need to write wrappers to your
   &foreign-function-t;s, while in &c-lang; you can do that directly.
   The same goes for <quote>polymorphism</quote>: accepting different
   argument types (like, e.g., &resolve-host; does) would require a lisp
   wrapper for &foreign-function-t;s.
</simpara></listitem></varlistentry>
<varlistentry><term>Learning curve: unclear</term>
 <listitem><simpara>If you are comfortable with &c-lang;, you might
   find the &clisp; &c-lang; module facilities (e.g., &modprep;) very
   easy to use.</simpara>
  <simpara>&clisp; &ffi-pac;, on the other hand, is quite high-level,
   so, if you are more comfortable with high-level languages, you might
   find it easier to write &ffi-pac; forms than &c-lang; code.
</simpara></listitem></varlistentry>
<varlistentry><term>Safety: unclear</term>
 <listitem><simpara>One can get a segfault either way: if your
   &def-call-out; form does not describe the &c-lang; function's
   expectations with respect to the arguments and return values
   (including &allocation;), you will probably learn that the hard way.
   If the module is written in &c-lang;, all the opportunities to shoot
   oneself in the foot (and other body parts) are wide open
   (although well known to most &c-lang; users).
   However, with &c-lang;, one has to watch
   for <link linkend="gc-safety">GC-safety</link> too.
</simpara></listitem></varlistentry>
<varlistentry><term>System requirements: &ffi-pac; wins</term>
 <listitem><para>Some &linux; distributions offer separate
 <emphasis>library</emphasis> (containing shared libraries only)
 and <emphasis>development</emphasis> (containing static libraries and
 &c-lang; headers) packages.<itemizedlist>
 <listitem><simpara>When <emphasis>developing</emphasis> using &ffi-pac;
  with &library-k; (and avoiding &def-c-const;), the
  <emphasis>development</emphasis> package is &not-e; needed.
 </simpara></listitem>
 <listitem><simpara>When <emphasis>developing</emphasis> with &modprep;,
  the <emphasis>development</emphasis> package &is-e; necessary.
 </simpara></listitem>
 <listitem><simpara>When <emphasis>distributing</emphasis> module (built
  with either &ffi-pac; or &modprep;), only the <emphasis>library</emphasis>
  package is needed.</simpara></listitem></itemizedlist></para></listitem>
</varlistentry></variablelist></para>
<note id="mod-ffi-vs-c-granularity"><simpara>The granularity of the
  choice is <emphasis>per function</emphasis>: the same module can use
  both &modprep; and &ffi-pac;.</simpara></note>
<note id="mod-ffi-vs-c-naming"><simpara>It is not a good idea to have
  both <filename>foo.lisp</filename> and <filename>foo.c</filename>
  files in a module, because if you ever add an &ffi-pac; form to the
  former, &compile-file-my; will
  <link linkend="c-file-overwrite">overwrite</link> the latter.</simpara></note>
</section>

<section id="included-modules">
   <title>Modules included in the source distribution</title>

<para>A few modules come with the <emphasis>source</emphasis>
 distribution of &clisp; (but are not necessarily built in a
 particular <emphasis>binary</emphasis> distribution).</para>

<para>To use modules, read <filename role="clisp-cvs">unix/INSTALL</filename>
 and build &clisp; in a directory <filename>build-dir</filename> with,
 e.g.,<screen>
&sh-prompt; ./configure --with-module=pcre --with-module=clx/new-clx --cbc build-dir</screen> then run it with
<screen>&sh-prompt; ./build-dir/clisp &opt-K; full</screen>
This will create a &base; &linkset; with modules
&i18n-mod;, &regexp-mod; and &syscalls-mod; (and maybe &readline-mod;);
and a &full; &linkset; with modules &new-clx; and &pcre-mod; in addition
to the 3 (or 4) &base; modules.</para>

<para>Here we list the included modules by their general theme.
 See <xref linkend="ext-modules"/> for individual module documentation.</para>

<section id="base-modules"><title>Base Modules</title>
 <para>The default build process includes the following modules
  in &both-e; &base; &and-e; &full; &linkset;s:
<variablelist><varlistentry><term>&i18n-mod;</term>
  <listitem><simpara>Internationalization of User Programs.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&regexp-mod;</term>
  <listitem><simpara>The &posix; <ulink url="regexp.html">Regular
     Expressions</ulink> matching, compiling, executing.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&syscalls-mod;</term>
  <listitem><simpara>Use some system calls in a platform-independent way.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&readline-mod; (only when &both-e; &readline; and
    &ffi-pac; are available)</term>
  <listitem><simpara>Some advanced readline and history features are exported
  using this module.</simpara></listitem></varlistentry></variablelist></para>
 <para>The composition of the &full; &linkset; depends on the platform
  and on the vendor preferences.</para>
</section>

<section id="incmod-db"><title>Database, Directory et al</title>
<variablelist><varlistentry><term>&gdbm-mod;</term>
  <listitem><simpara>Interface to &gdbm; by
    <author><firstname>Masayuki</firstname><surname>Onjo</surname>
     <email>masayuki.onjo@gmail.com</email></author>.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&berkeley-db-mod;</term>
  <listitem><simpara><ulink role="bdb" url="index.html">Berkeley DB</ulink>
    interface.</simpara></listitem></varlistentry>
 <varlistentry><term>&dirkey-mod;</term>
  <listitem><simpara>Directory Access (LDAP, &win32; registry etc).
 </simpara></listitem></varlistentry>
 <varlistentry><term>&postgresql-mod;</term>
  <listitem><simpara>Access &postgresql-link; from &clisp;.
  </simpara></listitem></varlistentry>
 <varlistentry><term>&oracle-mod;</term>
  <listitem><simpara>Access &oracle-link; RDBMS from &clisp;; by &hin;.
 </simpara></listitem></varlistentry>
</variablelist></section>

<section id="incmod-kdml"><title>Mathematics, Data Mining et al</title>
<variablelist><varlistentry><term>&libsvm-mod;</term>
  <listitem><simpara>Build
    <ulink url="http://www.support-vector-machines.org/">Support
     Vector Machine</ulink> models using &libsvm-link; inside &clisp;.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&pari-mod;</term>
  <listitem><simpara>Interface to the computer algebra system &pari-link;.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&matlab-mod;</term>
  <listitem><simpara>Do matrix computations via
    <ulink url="http://www.mathworks.com/products/matlab/">MATLAB</ulink>.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&netica-mod;</term>
  <listitem><simpara>Work with Bayesian belief networks and influence
    diagrams using &netica-link;.</simpara></listitem></varlistentry>
</variablelist></section>

<section id="incmod-match"><title>Matching, File Processing et al</title>
<variablelist><varlistentry><term>&pcre-mod;</term>
  <listitem><simpara>The &pcre-link; matching, compiling, executing.
 </simpara></listitem></varlistentry>
 <varlistentry><term>&zlib-mod;</term>
  <listitem><simpara>Compress &vector-t;s using &zlib-link;.
 </simpara></listitem></varlistentry>
</variablelist></section>

<section id="incmod-net"><title>Communication, Networking</title>
<variablelist><varlistentry><term>&rawsock-mod;</term>
  <listitem><simpara>Raw socket access.</simpara></listitem></varlistentry>
<varlistentry><term>&dbus-mod;</term>
  <listitem><simpara>Interface to &d-bus-link;.
</simpara></listitem></varlistentry>
 <varlistentry><term>&fastcgi-mod;</term>
  <listitem><simpara>Access &fastcgi-link; from &clisp;;
    by &hin;.</simpara></listitem></varlistentry>
</variablelist></section>

<section id="incmod-gui"><title>Graphics</title>
<variablelist><varlistentry><term>&clx;</term>
 <listitem><para>Call
   <ulink url="http://www.x.org/docs/X11/xlib.pdf">Xlib</ulink>
   functions from &clisp;.  Two implementations are supplied:
  <variablelist><varlistentry><term>&mit-clx;, from MIT
   <ulink url="ftp://ftp.x.org/R5contrib/CLX.R5.02.tar.Z"/></term>
   <listitem><simpara>the standard implementation
  </simpara></listitem></varlistentry>
  <varlistentry><term>&new-clx;, by &gilbert-baumann;</term>
   <listitem><para>faster, with additional features, but not quite complete yet.
    Please try it first and use &mit-clx; only
    if &new-clx; does not work for you.
    &new-clx; comes with several demos, please try them using
    <screen>&sh-prompt; &clisp-cmd; &opt-K; &full; &opt-i; <filename role="clisp-cvs">modules/clx/new-clx/demos/clx-demos.lisp</filename> &opt-x; '(clx-demos:run-all-demos)'</screen>
     and follow the intructions.</para></listitem></varlistentry>
 </variablelist>This functionality is documented in the manual
  <ulink url="http://www.stud.uni-karlsruhe.de/~unk6/clxman/"/>, also
  available in the &clisp; source distribution as
  <filename role="clisp-cvs">modules/clx/clx-manual.tar.gz</filename>.
 </para></listitem></varlistentry>
 <varlistentry><term>&gtk2-mod;</term>
  <listitem><simpara>Use &gtk; and &glade; to create GUI by
    <author><firstname>James</firstname><surname>Bailey</surname>
     <email>dgym.bailey@gmail.com</email></author>.
 </simpara></listitem></varlistentry>
</variablelist></section>

<section id="incmod-bind"><title>Bindings</title>
 <para>Call the operating system functions from &clisp;.
  The following platforms are supported:<variablelist>
   <varlistentry><term>&glibc-mod;</term>
    <listitem><simpara>&linux;/&glibc;</simpara></listitem></varlistentry>
   <varlistentry><term>&win32-mod;</term>
    <listitem><simpara>&win32;</simpara></listitem></varlistentry>
</variablelist></para></section>

<section id="incmod-toys"><title>Toys and Games</title>
<variablelist><varlistentry><term>&queens-mod;</term>
  <listitem><simpara>Compute the number of solutions to the &n-r;-queens
    problem on a &n-r;&times;&n-r; chessboard (a toy
    example for the users to explore the &clisp; &module; system).
 </simpara></listitem></varlistentry>
 <varlistentry><term><filename role="clisp-cvs">modules/clx/new-clx/demos/sokoban.lisp</filename></term>
  <listitem><simpara>a demo which comes with &new-clx;.
</simpara></listitem></varlistentry></variablelist></section>

<section id="incmod-misc"><title>Miscellaneous</title>
<variablelist><varlistentry><term>&asdf-mod;</term>
  <listitem><simpara>A system definition facility.
 </simpara></listitem></varlistentry></variablelist></section>

</section>

</section>
<!-- #endif -->

<!-- #ifdef DYNAMIC_FFI -->
<section id="dffi"><title>The Foreign Function Call Facility</title>
<subtitle><emphasis role="plat-dep">Many &unix;, &win32; platforms
  only.</emphasis></subtitle>

<section id="dffi-intro"><title>Introduction</title>

<para>This facility, also known as <quote>Foreign Language Interface</quote>,
allows one to call a function implemented in &c-lang; from inside &clisp;
and to do many related things, like inspect and modify foreign memory,
define a <quote>callback</quote> (i.e., make a lisp function available
to the &c-lang; world), etc.
To use this facility, one writes a <firstterm>foreign function
  <indexterm id="dffi-ff"><primary>foreign function</primary>
 </indexterm></firstterm> description into an
ordinary Lisp file, which is then compiled and loaded as usual;
or just evaluates the appropriate form in the &repl;.</para>

<para>There are two basic ways to do define a foreign function:<orderedlist>
<listitem><simpara>Use &dlopen; and &dlsym; to get to the location of the
  function code in a dynamic library.
  To access this facility, pass the &library-k; option to &def-call-out;
  and &def-c-var;.</simpara>
  <simpara>Unfortunately, this functionality is not available on some
  operating systems, and, also, it offers only a part of the foreign
  functionality: &cpp; macros and <literal>inline</literal> functions
  cannot be accessed this way.  On the other hand, this functionality
  is available in the &repl; and does not require a &c-lang; compiler.
</simpara></listitem>
<listitem><simpara>Use a somewhat less direct way: when you do not use
  the &library-k; argument, &compile-file-my; produces a &c-file; file
  (in addition to a &fasl-file; and a &lib-file;).
  Then you compile (with a &c-lang; compiler) and link it into &clisp;
  (statically, linking it into <filename>lisp.a</filename>, or
  dynamically, loading it into a running &clisp; using &dlopen; and &dlsym;).
  This way you can use any functionality your foreign library exports,
  whether using ordinary functions, <literal>inline</literal> functions,
  or &cpp; macros (see <xref linkend="dffi-ex-macro"/>).
 </simpara></listitem></orderedlist>
</para>

<para>All symbols relating to the foreign function interface are
 exported from the package &ffi-pac;.
 To use them, <code>(&use-package; &ffi-pac;)</code>.</para>

<para>Special &ffi-pac; forms may appear anywhere in the Lisp file.</para>

</section>

<section id="dffi-overview"><title>Overview</title>

<para>These are the special &ffi-pac; forms.  We have taken a pragmatic
 approach: the only foreign languages we support for now are &c-lang;
 and &the-ansi; &c-lang;.</para>

<note><simpara>Unless specifically noted otherwise, type specification
  parameters are &not-e; evaluated, so that they can be compiled by
  &parse-c-type; into the internal format at macroexpansion time.
</simpara></note>

<variablelist><title>High-level &ffi-pac; forms; &name-r; is any Lisp
   &symbol-t;; &cname-r; is a &string-t;</title>
<varlistentry id="def-c-type">
 <term><code>(&def-c-type; &name-r; &optional-amp; &ctype-r;)</code></term>
 <listitem><simpara>This form makes &name-r; a shortcut for &ctype-r;.
   Note that &ctype-r; may already refer to &name-r;.
   Forward declarations of types are not possible, however.</simpara>
  <simpara>When &ctype-r; is omitted, the type is assumed to be an
   integer, and its size and signedness are determined at link time,
   e.g., <code>(&def-c-type; size_t)</code>.</simpara>
</listitem></varlistentry>

<varlistentry id="def-c-var"><term><code>(&def-c-var; &name-r;
   {&option-r;}*)</code></term>
<listitem><simpara>This form defines a &foreign-variable-t;.
  &name-r; is the Lisp name, a regular Lisp &symbol-t;.</simpara>
 <variablelist id="def-c-var-opts"><title>Options for &def-c-var;</title>
<varlistentry><term><code>(&name-k; &cname-r;)</code></term>
 <listitem><simpara>specifies the name as seen from &c-lang;, as a
   &string-t;.  If not specified, it is derived from the print name of
   the Lisp name.</simpara></listitem></varlistentry>
<varlistentry><term><code>(&type-k; &ctype-r;)</code></term>
 <listitem><simpara>specifies the variable's foreign type.
</simpara></listitem></varlistentry>
<varlistentry><term><code>(&ro-k; &boolean-t;)</code></term>
 <listitem><simpara>If this option is specified and non-&nil;,
   it will be impossible to change the variable's value from within
   Lisp (using &setq; or similar).</simpara></listitem></varlistentry>
<varlistentry><term><code>(:ALLOC &allocation;)</code></term>
 <listitem><simpara>This option can be either &none-k; or
   &malloc-free-k; and defaults to &none-k;.
   If it is &malloc-free-k;, any values of type &c-string;, &c-ptr;,
   &c-ptr-null;, &c-array-ptr; within the foreign value are assumed
   to be pointers to &malloc;-allocated storage, and when &setq;
   replaces an old value by a new one, the old storage is freed using
   &free; and the new storage allocated using &malloc;.
   If it is &none-k;, &setq; assumes that the pointers point to good
   storage (not &c-NULL;!) and overwrites the old values by the new ones.
   This is dangerous (just think of overwriting a string with a longer
   one or storing some data in a &c-NULL; pointer...) and deprecated.
</simpara></listitem></varlistentry>
<varlistentry><term><code>(&library-k; &name-r;)</code></term>
 <listitem><simpara>Specifies the (optional) dynamic library
   which contains the variable, the default is set by
   &default-foreign-library;.</simpara></listitem></varlistentry>
<varlistentry><term><code>(&version-k; &version-r;)</code></term>
 <listitem><simpara>Specifies the (optional) symbol version in the library
   (therefore, if &version-k; is supplied, &library-k; must also be supplied)
</simpara></listitem></varlistentry>
<varlistentry><term><code>(&documentation-k; &string-r;)</code></term>
 <listitem><simpara>Specifies the (optional) &variable-doc; documentation.
</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>

<varlistentry id="def-c-const"><term><code>(&def-c-const; &name-r;
   {&option-r;}*)</code></term>
 <listitem><para>This form defines a Lisp &constant; &name-r; whose value is
   determined at build time using an internal &foreign-function-t;.</para>
  <variablelist id="def-c-const-opts"><title>Options for &def-c-const;</title>
   <varlistentry><term><code>(&name-k; &cname-r;)</code></term>
    <listitem><simpara>specifies the name as seen from &c-lang;, as a
      &string-t;.  If not specified, it is derived from the print name
      of the Lisp name.</simpara></listitem></varlistentry>
   <varlistentry><term><code>(&type-k; &ctype-r;)</code></term>
    <listitem><para>specifies the constant's foreign type, one of
      <simplelist><member><type>FFI:INT</type></member>
       <member>&c-string;</member><member>&c-pointer;</member>
   </simplelist></para></listitem></varlistentry>
   <varlistentry><term><code>(<constant>:GUARD</constant>
      &string-r;)</code></term>
    <listitem><para>specifies the &cpp; check to wrap around &cname-r;,
      defaults to <literal role="data">"defined(&cname-r;)"</literal>;
      can be &nil; to omit the test. When the test fails, &name-r; is
      unbound.</para></listitem></varlistentry>
   <varlistentry><term><code>(&documentation-k; &string-r;)</code></term>
    <listitem><simpara>Specifies the (optional) &variable-doc; documentation.
  </simpara></listitem></varlistentry></variablelist>
  <simpara>See also <xref linkend="dffi-ex-macro"/>.</simpara>
</listitem></varlistentry>

<varlistentry id="def-call-out"><term><code>(&def-call-out;
              &name-r; {&option-r;}*)</code></term>
<listitem><simpara>This form defines a named call-out function (a
 foreign function called from Lisp: control flow temporarily leaves Lisp).
 </simpara><variablelist id="def-call-out-opts">
  <title>Options for &def-call-out;</title>
<varlistentry><term><code>(&name-k; &cname-r;)</code></term>
<listitem><simpara>Any Lisp function call to <function>#'&name-r;</function>
  is redirected to call the &c-lang; function &cname-r;.
</simpara></listitem></varlistentry>
<varlistentry><term><code>(&arguments-k;
   {(&arg-r; &ctype-r; [&param-mode; [&allocation;]])}*)</code></term>
 <term><code>(&ret-type-k; &ctype-r; [&allocation;])</code></term>
 <listitem><simpara>Argument list and return value, see
   <xref linkend="allocation"/> and <xref linkend="param-mode"/>.
</simpara></listitem></varlistentry>
<varlistentry><term><code>(&lang-k; &lang-r;)</code></term>
 <listitem><simpara>See <xref linkend="c-flavor"/>.
</simpara></listitem></varlistentry>
<varlistentry><term><code>(:BUILT-IN &boolean-t;)</code></term>
 <listitem><simpara>When the function is a &c-lang; built-in, the full
   prototype will be output (unless suppressed by &ffi-out-fun;).
</simpara></listitem></varlistentry>
<varlistentry><term><code>(&library-k; &name-r;)</code></term>
 <listitem><simpara>Specifies the (optional) dynamic library
   which contains the function, the default is set by
   &default-foreign-library;.</simpara></listitem></varlistentry>
<varlistentry><term><code>(&version-k; &version-r;)</code></term>
 <listitem><simpara>Specifies the (optional) symbol version in the library
   (therefore, if &version-k; is supplied, &library-k; must also be supplied).
</simpara></listitem></varlistentry>
<varlistentry><term><code>(&documentation-k; &string-r;)</code></term>
 <listitem><simpara>Specifies the (optional) &function-doc; documentation.
</simpara></listitem></varlistentry></variablelist>
 <simpara>See also <xref linkend="dffi-functions"/>.</simpara>
</listitem></varlistentry>

<varlistentry id="def-call-in"><term><code>(&def-call-in;
   &func-r; {&option-r;}*)</code></term>
<listitem><simpara>This form defines a
  <firstterm>callback<indexterm id="def-call-in-callback">
    <primary>callback</primary></indexterm></firstterm> -
  a named call-in function (i.e., a Lisp function called from the
  foreign language: control flow temporary enters Lisp)</simpara>
 <variablelist id="def-call-in-opts">
  <title>Options for &def-call-in;</title>
<varlistentry><term><code>(&name-k; &cname-r;)</code></term>
 <listitem><simpara>Any &c-lang; function call to the &c-lang; function
   &cname-r; is redirected to call the &cl; function &func-r;, which
   should be a &funname;.</simpara></listitem></varlistentry>
<varlistentry><term><code>(&arguments-k;
   {(&arg-r; &ctype-r; [&param-mode; [&allocation;]])}*)</code></term>
 <term><code>(&ret-type-k; &ctype-r; [&allocation;])</code></term>
 <listitem><simpara>Argument list and return value, see
   <xref linkend="allocation"/> and <xref linkend="param-mode"/>.
</simpara></listitem></varlistentry>
<varlistentry><term><code>(&lang-k; &lang-r;)</code></term>
 <listitem><simpara>See <xref linkend="c-flavor"/>.
</simpara></listitem></varlistentry></variablelist>
 <simpara>See also <xref linkend="dffi-functions"/>.</simpara>
</listitem></varlistentry>

<varlistentry id="dffi-open-lib"><term><code>(&open-foreign-library;
   &name-r; &key-amp; :REQUIRE)</code></term>
 <listitem><simpara>Open (load) a shared foreign library.</simpara>
  <simpara>Some shared libraries depend on other shared libraries
   and this dependency can be specified using
   the <constant>:REQUIRE</constant> argument.</simpara>
  <simpara>Unless the library has dependencies, this is only needed if
   you want to test for <emphasis>presence</emphasis> of a library
   without creating a foreign object referencing its contents.
   When you create a &foreign-variable-t; or a &foreign-function-t;
   using &def-c-var; or &def-call-out; with a &library-k; argument,
   the library &name-r; is opened automatically.</simpara>
  <para>E.g., <filename>libgsl.so</filename>
  requires <filename>libgslcblas.so</filename>:<programlisting language="lisp">
(&open-foreign-library; "libgsl.so")
*** - FFI:OPEN-FOREIGN-LIBRARY: Cannot open library "libgsl.so": "/usr/lib64/libgsl.so: undefined symbol: cblas_ctrmv"
</programlisting> so a common way is to pre-open the dependency:
<programlisting language="lisp">
(&open-foreign-library; "libgslcblas.so")
(&def-call-out; gsl_cheb_alloc (&library-k; "libgsl.so") (:language :stdc)
  (:arguments (n ffi:int)) (:return-type ffi:c-pointer))
<computeroutput>GSL_CHEB_ALLOC</computeroutput>
</programlisting> Alas, this would work <emphasis>in the current
 image</emphasis> only: if you save the
 image, <function>GSL_CHEB_ALLOC</function> will &not-e; work there
 because &clisp; will try to re-open <filename>libgsl.so</filename> and
 fail as above.  However, using the <constant>:REQUIRE</constant> argument
 will tell &clisp; to re-open &both-e; libraries in the right order:<screen>
&sh-prompt; clisp
&gt; (&open-foreign-library; "libgsl.so" :require '("libgslcblas.so"))
&gt; (&def-call-out; gsl_cheb_alloc (:library "libgsl.so") (:language :stdc)
  (:arguments (n ffi:int)) (:return-type ffi:c-pointer))
&gt; (&savemem; "foo" :executable t)
&gt; (&exit;)
&sh-prompt; ./foo
&gt; (gsl_cheb_alloc 10)
<computeroutput>#&lt;&foreign-address-t; #x0000000017AC38A0&gt;</computeroutput>
</screen></para></listitem></varlistentry>

<varlistentry id="dffi-close-lib"><term><code>(&close-foreign-library;
   &name-r;)</code></term>
 <listitem><simpara>Close (unload) a shared foreign library (opened by
   &open-foreign-library; or the &library-k; argument to &def-call-out;
   or &def-c-var;).</simpara>
  <simpara>If you want to modify your shared library, you need to close
   it using &close-foreign-library; first.  When you use a
   &foreign-variable-t; or a &foreign-function-t; which resides in the
   library &name-r;, it will be re-opened automatically.
</simpara></listitem></varlistentry>

<varlistentry id="dffi-default-lib"><term><code>(&default-foreign-library;
   &lib-name;)</code></term>
 <listitem><simpara>This macro sets the default &library-k; argument for
   &def-call-out; and &def-c-var;.  &lib-name; should be &nil;
   (meaning use the &c-lang; file produced by &compile-file-my;), a
   &string-t;, or, depending on the underlying &dlsym;
   or <function role="bsd">dlvsym</function> implementation,
   &default-k; or <constant>:NEXT</constant>.</simpara>
  <simpara>The default is set separately in each &comp-unit;, so, if you
   are interfacing to a single library, you can set this variable in the
   beginning of your lisp file and omit the &library-k; argument
   throughout the file.</simpara></listitem></varlistentry>

<varlistentry id="def-c-struct"><term><code>(&def-c-struct;
   &name-r; (&symbol-r; &ctype-r;)*)</code></term>
 <listitem><para>This form defines &name-r; to be both a
  &structure-class; and a foreign &c-lang; type with the given slots.
  If this class representation overhead is not needed one should consider
  writing <code>(&def-c-type; &name-r; (&c-struct;
  {&list-t; | &vector-t;} (&symbol-r; &ctype-r;)*))</code> instead.
  &name-r; is a &symbol-t; (structure name) or a &list-t; whose &first;
  element is the structure name and the &rest; is options.
  Two options are supported at this time:
  <variablelist id="def-c-struct-opts">
   <title>Options for &def-c-struct;</title>
   <varlistentry id="def-c-struct-typedef">
    <term><constant>:TYPEDEF</constant></term>
    <listitem><simpara>means that the name of this structure is a
      &c-lang; type defined with <function>typedef</function>
      elsewhere.</simpara></listitem></varlistentry>
   <varlistentry id="def-c-struct-external"><term>&external-k;</term>
    <listitem><simpara>means that this structure is defined in a
      &c-lang; header file that you include with, e.g.,
      <code>(&c-lines; "#include &lt;filename.h&gt;~%")</code>.
  </simpara></listitem></varlistentry></variablelist>
  These options determine how the struct is written to the &c-file;.
</para></listitem></varlistentry>

<varlistentry id="def-c-enum"><term><code>(&def-c-enum;
   &name-r; {&symbol-r; | (&symbol-r; [&value-r;])}*)</code></term>
 <listitem><simpara>This form defines &symbol-r;s
  as constants, similarly to the &c-lang; declaration <type>enum {
  &symbol-r; [= &value-r;], ... };</type></simpara>
<simpara>You can use <code>(<function>FFI:ENUM-FROM-VALUE</function>
  &name-r; &value-r;)</code> and
 <code>(<function>FFI:ENUM-TO-VALUE</function> &name-r;
  &symbol-r;)</code> to convert between the numeric and symbolic
 representations (of course, the latter function boils down to
 &symbol-value; plus a check that the &symbol-r; is indeed a constant
 defined in the &def-c-enum; &name-r;).</simpara></listitem></varlistentry>

<varlistentry id="c-lines"><term><code>(&c-lines; &fmt-r;
   {&arg-r;}*)</code></term>
 <listitem><simpara>This form outputs the string
   <code>(&format; &nil; &fmt-r; {&arg-r;}*)</code>
   to the &c-lang; output file's top level.
   This is usually used to include the relevant header files,
   see <xref linkend="def-c-struct-external"/>
   and <xref linkend="ffi-extern-output"/>.</simpara>
  <para>When &fmt-r; is not a &string-t;, is should be a &symbol-t;,
   and then the &string-t; <code>(&format; &nil; {&arg-r;}*)</code>
   is added to the appropriate &c-lang; function:<variablelist>
    <varlistentry><term><constant>:INIT-ALWAYS</constant></term>
     <term><constant>:INIT-ONCE</constant></term>
     <listitem><simpara><link linkend="modinit">initialization
        function</link></simpara></listitem></varlistentry>
    <varlistentry><term><constant>:FINI</constant></term>
     <listitem><simpara><link linkend="modfini">finalization
        function</link></simpara></listitem></varlistentry>
</variablelist></para></listitem></varlistentry>

<varlistentry id="element"><term><code>(&element; &cplace-r; &index1-r;
     ... &indexn-r;)</code></term>
 <listitem><simpara>Array element: If &cplace-r; is of foreign type
   <literal role="type">(&c-array; &ctype-r; (&dim1-r; ... &dimn-r;))</literal>
   and 0 &le; &index1-r; &lt; &dim1-r;, ..., 0 &le; &indexn-r; &lt; &dimn-r;,
   this will be the &place; corresponding to <code>(&aref; &cplace-r;
   &index1-r; ... &indexn-r;)</code> or
   <varname>&cplace-r;[&index1-r;]...[&indexn-r;]</varname>.
   It is a &place; of type &ctype-r;.
   If &cplace-r; is of foreign type <literal role="type">(&c-array-max;
    &ctype-r; &dim-r;)</literal> and 0 &le; &index-r; &lt; &dim-r;,
   this will be the &place; corresponding to <code>(&aref; &cplace-r;
    &index-r;)</code> or <varname>&cplace-r;[&index-r;]</varname>.
   It is a &place; of type &ctype-r;.
</simpara></listitem></varlistentry>

<varlistentry id="deref"><term><code>(&deref; &cplace-r;)</code></term>
<listitem><simpara>Dereference pointer: If
  &cplace-r; is of foreign type
  <literal role="type">(&c-ptr; &ctype-r;)</literal>,
  <literal role="type">(&c-ptr-null; &ctype-r;)</literal> or
  <literal role="type">(&c-pointer; &ctype-r;)</literal>,
  this will be the &place; the pointer points to.
  It is a &place; of type &ctype-r;.
  For <literal role="type">(&c-ptr-null; &ctype-r;)</literal>,
  the &cplace-r; may not be &c-NULL;.
</simpara></listitem></varlistentry>

<varlistentry id="slot"><term><code>(&slot; &cplace-r;
   &slot-name-r;)</code></term>
 <listitem><simpara>Struct or union component: If &cplace-r; is of
   foreign type <literal role="type">(&c-struct; &class-r; ...
    (&slot-name-r; &ctype-r;) ...)</literal> or of
   type <literal role="type">(&c-union;
    ... (&slot-name-r; &ctype-r;) ...)</literal>,
   this will be of type &ctype-r;.</simpara></listitem></varlistentry>

<varlistentry id="cast"><term><code>(&cast;
           &cplace-r; &ctype-r;)</code></term>
<listitem><simpara>Type change: A &place; denoting the same memory
  locations as the original &cplace-r;, but of type &ctype-r;.
 </simpara></listitem></varlistentry>

<varlistentry id="offset"><term><code>(&offset;
           &cplace-r; &offset-r; &ctype-r;)</code></term>
<listitem><simpara>Type change and displacement: return a &place; denoting
  a memory locations displaced from the original &cplace-r; by an
  &offset-r; counted in bytes, with type &ctype-r;.
  This can be used to resize an array, e.g. of &ctype-r;
  <literal role="type">(&c-array; <type>uint16</type> &n-r;)</literal>
  via <code>(&offset; &cplace-r; 0 '(&c-array; <type>uint16</type>
   &k-r;))</code>.
 </simpara></listitem></varlistentry>

<varlistentry id="c-var-addr"><term><code>(&c-var-addr;
           &cplace-r;)</code></term>
<listitem><simpara>Return the address of &cplace-r; as a Lisp object of
  type &foreign-address-t;.  This is useful as an argument
  to foreign functions expecting a parameter of &c-lang; type &c-pointer;.
 </simpara></listitem></varlistentry>

<varlistentry id="c-var-object"><term><code>(&c-var-object;
   &cplace-r;)</code></term>
 <listitem><simpara>Return the &foreign-variable-t; object underlying the
   &cplace-r;.  This is also an acceptable argument type to a &c-pointer;
   declaration.</simpara></listitem></varlistentry>

<varlistentry id="typeof"><term><code>(&typeof; &cplace-r;)</code></term>
 <listitem><simpara>returns the &ctype-r; corresponding to the &cplace-r;.
</simpara></listitem></varlistentry>

<varlistentry id="sizeof"><term><code>(&sizeof; &ctype-r;)</code></term>
 <term><code>(&sizeof; &cplace-r;)</code></term>
 <listitem><simpara>The first form returns the size and alignment of the
   &c-lang; type &ctype-r;, measured in bytes.</simpara>
  <simpara>The second form returns the size and alignment of the
   &c-lang; type of &cplace-r;, measured in bytes.
</simpara></listitem></varlistentry>

<varlistentry id="bitsizeof"><term><code>(&bitsizeof; &ctype-r;)</code></term>
 <term><code>(&bitsizeof; &cplace-r;)</code></term>
 <listitem><simpara>The first form returns the size and alignment of the
   &c-lang; type &ctype-r;, measured in bits.</simpara>
  <simpara>The second form returns the size and alignment of the
   &c-lang; type of &cplace-r;, measured in bits.
</simpara></listitem></varlistentry>

<varlistentry id="faddr-u">
 <term><code>(&foreign-address-unsigned; &f-ent;)</code></term>
 <term><code>(&unsigned-foreign-address; &number-r;)</code></term>
 <listitem><simpara>&foreign-address-unsigned; returns the &integer-t;
   address embodied in the Lisp object of type &foreign-address-t;,
   &foreign-pointer-t;, &foreign-variable-t; or &foreign-function-t;.</simpara>
  <simpara>&unsigned-foreign-address; returns a &foreign-address-t;
   object pointing to the given &integer-t; address.
</simpara></listitem></varlistentry>

<varlistentry id="faddr">
 <term><code>(&foreign-address; &f-ent;)</code></term>
 <listitem><simpara>&foreign-address; is both a type name and a
   selector/constructor function. It is the Lisp object type
   corresponding to a &c-pointer; external type declaration, e.g. a
   call-out function with <code>(&ret-type-k; &c-pointer;)</code> yields
   a Lisp object of type &foreign-address-t;.</simpara>
  <simpara>The function extracts the object of type &foreign-address-t;
   living within any &foreign-variable-t; or &foreign-function-t; object.
   If the &f-ent; already is a &foreign-address-t;, it returns it.
   If it is a &foreign-pointer-t; (e.g. a base foreign library address),
   it encapsulates it into a &foreign-address-t; object, as suitable
   for use with a &c-pointer; external type declaration.
   It does not construct addresses out of &number-t;s,
   &unsigned-foreign-address; must be used for that purpose.
</simpara></listitem></varlistentry>

<varlistentry id="dffi-make-var"><term><code>(&foreign-variable; &f-ent;
   &ctypei-r; &key-amp; &name-r;)</code></term>
 <listitem><simpara> This constructor creates a new &foreign-variable-t;
   from the given &foreign-address-t; or &foreign-variable-t; and the
   internal &c-lang; type descriptor (as obtained from &parse-c-type;).
   &name-r;, a &string-t;, is mostly useful for documentation and
   interactive debugging since it appears in the printed representation
   of the &foreign-variable-t; object, as in
   <computeroutput>#&lt;&foreign-variable-t; "foo"
    #x0ADD4E55&gt;</computeroutput>.
   In effect, this is similar to &cast; (or rather
   <code>(&offset; ... 0 ...)</code> for places),
   except that it works with &foreign-address; objects and allows
   caching of the internal &c-lang; types.</simpara></listitem></varlistentry>

<varlistentry id="dffi-make-func"><term><code>(&foreign-function;
   &f-ent; &ctypei-r; &key-amp; &name-r;)</code></term>
 <listitem><simpara>This constructor creates a &foreign-function-t;
   from the given &foreign-address-t; or &foreign-function-t; and the
   internal &c-lang; type descriptor (as obtained from
   <code>(&parse-c-type; '(&c-function; ...))</code>,
   in which case it is important to specify the &lang-k; because the
   expressions are likely to be evaluated at run time, outside the &comp-unit;).
   The &name-r;, a &string-t;, is mostly useful for documentation and
   interactive debugging since it appears in the printed representation
   of the &foreign-function-t; object, e.g.,
   <computeroutput>#&lt;&foreign-function-t; "foo"
    #x0052B060&gt;</computeroutput>.
   It is inherited from the given &foreign-function-t; object when
   available.</simpara>
  <simpara>See also <xref linkend="dffi-functions"/>.</simpara>
</listitem></varlistentry>

<varlistentry id="validp"><term><code>(&validp; &f-ent;)</code></term>
  <term><code>(&setf; (&validp; &f-ent;) &value-r;)</code></term>
<listitem><simpara>This predicate returns &nil; if the &f-ent;
  (e.g. the Lisp equivalent of a &c-pointer;) refers to a pointer
  which is invalid (e.g., because it comes from a previous Lisp session).
  It returns &t; if &f-ent; can be used within the current Lisp process
  (thus it returns &t; for all non-foreign arguments).</simpara>
 <simpara>You can invalidate a foreign object using
  <code>(&setf; &validp;)</code>.
  You cannot resurrect a zombie, nor can you kill a non-foreign object.
</simpara></listitem></varlistentry>

<varlistentry id="fptr"><term><code>(&foreign-pointer; &f-ent;)</code></term>
 <listitem><simpara>&foreign-pointer; returns the &foreign-pointer-t;
   associated with the Lisp object of type &foreign-address-t;,
   &foreign-pointer-t;, &foreign-variable-t; or &foreign-function-t;.
</simpara></listitem></varlistentry>

<varlistentry><term><code>(&set-foreign-pointer; &f-ent; {&f-ent; |
   &copy-k;})</code></term>
 <listitem><simpara>&set-foreign-pointer; changes the
   &foreign-pointer-t; associated with the Lisp object of type
   &foreign-address-t;, &foreign-variable-t; or &foreign-function-t; to
   that of the other entity.
   With &copy-k;, a &fresh; &foreign-pointer-t; is allocated.
   The original &f-ent; still points to the same object and is returned.
   This is particularly useful with <code>(&setf; &validp;)</code>,
   see <xref linkend="ex-dffi-validity"/>.</simpara></listitem></varlistentry>

<varlistentry id="foreign-stack">
  <term><code>(&with-foreign-object; (&var-r; &ctype-r;
      [<replaceable>initarg</replaceable>]) &body-r;)</code></term>
  <term><code>(&with-c-var; (&var-r; &ctype-r;
      [<replaceable>initarg</replaceable>]) &body-r;)</code></term>
<listitem><simpara>These forms allocate space on the &c-lang; execution
  stack, bind respectively a &foreign-variable-t; object or
  a local &symbol-macro; to &var-r; and execute &body-r;.</simpara>
  <simpara>When <replaceable>initarg</replaceable> is not supplied,
  they allocate space only for <code>(&sizeof; &ctype-r;)</code> bytes.
  This space is filled with zeroes.  E.g.,
  using a &ctype-r; of &c-string; or even <literal role="type">(&c-ptr;
  (&c-array; <type>uint8</type> 32))</literal> (!) both allocate space
  for a single pointer, initialized to &c-NULL;.</simpara>
  <para>When <replaceable>initarg</replaceable> is supplied, they
  allocate space for an arbitrarily complex set of structures rooted in
  &ctype-r;.  Therefore, &c-array-max;, <literal role="data">#()</literal>
  and <literal role="data">""</literal> are your friends for creating a
  pointer to the empty arrays:
<programlisting language="lisp">(with-c-var (v '(c-ptr (c-array-max uint8 32)) #())
  (setf (element (deref v) 0) 127) v)</programlisting>
  &ctype-r; is evaluated, making creation of variable sized buffers easy:
<programlisting language="lisp">(with-c-var (fv `(c-array uint8 ,(length my-vector)) my-vector)
  (print fv))</programlisting>
 </para></listitem></varlistentry>

<varlistentry id="foreign-value">
 <term><code>(&foreign-value; &foreign-variable;)</code></term>
 <term><code>(&setf; (&foreign-value; &foreign-variable;) ...)</code></term>
 <listitem><simpara>This functions converts the reference to a &c-lang;
  data structure which the &foreign-variable; describes, to Lisp. Such a
  reference is typically obtained from &allocate-shallow;,
  &allocate-deep;, &foreign-allocate; or via a <code>(&c-pointer;
  &ctype-r;)</code> &c-lang; type description.
  Alternatively, macros like &with-c-place; or &with-c-var; and the
  concept of foreign &place; hide many uses of this function.</simpara>
 <simpara>The &setf; form performs conversion from Lisp to &c-lang;,
  following to the &foreign-variable;'s type description.
</simpara></listitem></varlistentry>

<varlistentry id="foreign-stack-string">
 <term><code>(&with-foreign-string;
   (&f-addr; <replaceable>char-count</replaceable>
    <replaceable>byte-count</replaceable> &string-r;
    &key-amp; &encoding-r; <replaceable>null-terminated-p</replaceable>
    &start-r; &end-r;) &body-amp; &body-r;)</code></term>
 <listitem><simpara>This forms converts a Lisp &string-r; according to
   the &encoding-r;, allocating space on the &c-lang; execution stack.
   &encoding-r; can be any &encoding;, e.g. &utf-16; or &utf-8;,
   whereas &foreign-enc; must be an &ascii;-compatible encoding.
   </simpara>
  <simpara>&body-r; is then executed with the three variables &f-addr;,
   <replaceable>char-count</replaceable> and
   <replaceable>byte-count</replaceable> respectively bound to an
   untyped &foreign-address-t; (as known from the &c-pointer; foreign
   type specification) pointing to the stack location, the number of
   &character-t;s of the Lisp &string-r; that were considered and the
   number of &ubyte-8; bytes that were allocated for it on the &c-lang;
   stack.</simpara>
  <simpara>When <replaceable>null-terminated-p</replaceable> is true,
   which is the default, a variable number of zero bytes is appended,
   depending on the encoding, e.g. 2 for &utf-16;,
   and accounted for in <replaceable>byte-count</replaceable>,
   and <replaceable>char-count</replaceable> is incremented by one.</simpara>
  <simpara>The &foreign-address-t; object bound to &f-addr; is
   invalidated upon the exit from the form.</simpara>
  <para>A stupid example (a quite costly interface
   to <function role="unix">mblen</function>):
<programlisting language="lisp">(with-foreign-string (fv elems bytes string
                      :encoding charset:jis... :null-terminated-p nil
                      :end 5)
 (declare (ignore fv elems))
 (format t "This string would take ~D bytes." bytes))</programlisting>
</para></listitem></varlistentry>

<varlistentry id="c-type-parse">
 <term><code>(&parse-c-type; &ctype-r;)</code></term>
 <term><code>(&deparse-c-type; &ctypei-r;)</code></term>
 <listitem><simpara>Convert between the external (&list-t;) and internal
   (&vector-t;) &c-lang; type representations (used by &describe-my;).
  </simpara><note><simpara>Although you can memoize a &ctypei-r; (see
    <xref linkend="memoized"/> - but do not expect type redefinitions to
    work across memoization!), you cannot serialize it (write to
    disk) because deserialization loses object identity.</simpara></note>
</listitem></varlistentry>

<varlistentry id="foreign-heap"><term><code>(&allocate-shallow;
   &ctype-r; &key-amp; &count-k; &ro-k;)</code></term>
 <term><code>(&allocate-deep; &ctype-r; &cont-r;
   &key-amp; &count-k; &ro-k;)</code></term>
 <term><code>(&foreign-free; &f-ent; &key-amp; :FULL)</code></term>
 <term><code>(&foreign-allocate; &ctypei-r;
   &key-amp; :INITIAL-CONTENTS &count-k; &ro-k;)</code></term>
 <listitem><simpara>Macro &allocate-shallow; allocates
   <code>(&sizeof; &ctype-r;)</code>
   bytes on the &c-lang; heap and zeroes them out
   (like <function role="unix">calloc</function>).
   When &count-k; is supplied, &ctype-r; is substituted with
   <literal role="type">(&c-array; &ctype-r; &count-r;)</literal>,
   except when &ctype-r; is &character-t;, in which case
   <literal role="type">(&c-array-max; &character-t; &count-r;)</literal>
   is used instead.
   When &ro-k; is supplied, the Lisp side is prevented from modifying the
   memory contents.  This can be used as an indication that some foreign
   side is going to fill this memory (e.g. via &read-U;).</simpara>
  <simpara>Returns a &foreign-variable-t; object of the actual &ctype-r;,
   whose address part points to the newly allocated memory.</simpara>
  <simpara>&allocate-deep; will call &c-lang; &malloc; as many times
   as necessary to build a structure on the &c-lang; heap of the given
   &ctype-r;, initialized from the given &cont-r;.</simpara>
  <simpara>E.g., <code>(&allocate-deep; '&c-string; "ABCDE")</code>
    performs 2 allocations: one for a &c-lang; pointer to a string,
    another for the contents of that string.  This would be useful in
    conjunction with a <type>char**</type> &c-lang; type
    declaration.  <code>(&allocate-shallow; '&c-string;)</code>
    allocates room for a single pointer (probably 4 bytes).</simpara>
  <simpara><code>(&allocate-deep; '&character-t; "ABCDEF" :count
    10)</code> allocates and initializes room for the type <literal
    role="type">(&c-array-max; &character-t; 10)</literal>,
    corresponding to <type>char*</type> or, more specifically,
   <type>char[10]</type> in &c-lang;.</simpara>
  <simpara>Function &foreign-free; deallocates memory at the address
   held by the given &f-ent;. If <constant>:FULL</constant> is supplied
   and the argument is of type &foreign-variable-t;, recursively frees
   the whole complex structure pointed to by this variable.</simpara>
  <simpara>If given a &foreign-function-t; object that corresponds to a
   &clisp; callback, deallocates it.  Callbacks are automatically
   created each time you pass a Lisp function via the &ffi-pac;.</simpara>
  <simpara>Use <code>(&setf; &validp;)</code> to disable further
   references to this address from Lisp.  This is currently not done
   automatically.  If the given pointer is already invalid,
   &foreign-free; (currently) &sig-err;. This may change to
   make it easier to integrate with &finalize;.</simpara>
   <simpara>Function &foreign-allocate; is a lower-level interface as it
   requires an internal &c-lang; type descriptor as returned by
   &parse-c-type;.</simpara></listitem></varlistentry>

<varlistentry id="with-c-place"><term><code>(&with-c-place; (&var-r; &f-ent;)
   &body-r;)</code></term>
 <listitem><simpara>Create a &place; out of the given &foreign-variable-t;
  object so operations on places (e.g. &cast;, &deref;, &slot; etc.) can
  be used within &body-r;.  &with-c-var; appears as a composition of
  &with-foreign-object; and &with-c-place;.</simpara>
  <para>Such a &place; can be used to access memory referenced by a &f-ent;
  object:
  <programlisting language="lisp">(setq foo (allocate-deep '(c-array uint8 3) rgb))
(with-c-place (place foo) (element place 0))</programlisting>
</para></listitem></varlistentry>

<varlistentry id="ffi-extern-output"><term>&ffi-out-fun;</term>
 <term><varname>FFI:*OUTPUT-C-VARIABLES*</varname></term>
 <listitem><simpara>&clisp; will write the <type>extern</type>
   declarations for foreign functions (defined with &def-call-out;) and
   foreign variables (defined with &def-c-var;) into the output &c-file;
   (when the Lisp file is compiled with &compile-file-my;)
   <emphasis>unless</emphasis> these variables are &nil;.
   They are &nil; by default, so the <type>extern</type>
   declarations are &not-e; written; you are encouraged to use
   &c-lines; to include the appropriate &c-lang; headers.
   Set these variables to non-&nil; if the headers are not available or
   not usable.</simpara></listitem></varlistentry>

<varlistentry id="ffi-guard"><term>&ffi-guard;</term>
<listitem><para>When this variable is non-&nil; at &compile-time;,
  &clisp; will guard the &c-lang; statements in the output file with
  &cpp; conditionals to take advantage of &autoconf; feature detection.
  E.g., <programlisting language="lisp">
(&eval-when; (compile) (setq *foreign-guard* t))
(&def-call-out; some-function (:name "function_name") ...)
</programlisting> will produce <programlisting language="C">
# if defined(HAVE_FUNCTION_NAME)
  register_foreign_function((void*)&amp;function_name,"function_name",1024);
# endif
</programlisting> and will compile and link on any system.</para>
 <simpara>This is mostly useful for product delivery when you want your
  module to build on any system even if some features will not be
  available.</simpara>
 <simpara>&ffi-guard; is initialized to &nil; for backwards compatibility.
</simpara></listitem></varlistentry>

<varlistentry id="fptr-info"><term>&foreign-pointer-info;</term>
 <listitem><simpara>This is an interface
   to <function role="bsd">dladdr</function> and it returns the 4 fields
   of <type>Dl_info</type> as &mul-val;.</simpara></listitem>
</varlistentry>

</variablelist>

<variablelist id="dffi-low"><title>Low-level &ffi-pac; forms</title>
<varlistentry id="memory-as">
 <term><code>(&memory-as; &f-addr; &ctypei-r; &optional-amp;
   &offset-r;)</code></term>
 <term><code>(&setf; (&memory-as; &f-addr; &ctypei-r; &optional-amp;
   &offset-r;) &value-r;)</code></term>
 <listitem><simpara>This accessor is useful when operating with untyped
   foreign pointers (&foreign-address-t;) as opposed to typed ones
   (represented by &foreign-variable-t;).  It allows to type and
   dereference the given pointer without the need to create an object of
   type &foreign-variable-t;.</simpara>
  <simpara>Alternatively, one could use <code>(&foreign-value;
    (&foreign-variable; &f-ent; &ctypei-r;))</code>
   (also &setf;able).</simpara>
  <simpara>Note that &ctypei-r; is the <emphasis>internal</emphasis>
   representation of a foreign type, thus &parse-c-type; is required
   with literal names or types, e.g. <code>(&memory-as; &f-addr;
    (&parse-c-type; '(&c-array; uint8 3)))</code> or <code>(&setf;
    (&memory-as; &f-addr; (&parse-c-type; 'uint32)) 0)</code>.</simpara>
</listitem></varlistentry>
</variablelist>

</section>

<section id="dffi-types"><title>(Foreign) &c-lang; types</title>

<para>Foreign &c-lang; types are used in the &ffi-pac;.
They are &not-e; regular &cl; types or &clos; classes.</para>

<para>A &ctype-r; is either a predefined &c-lang; type or the name of a
 type defined by &def-c-type;.</para>

<variablelist><title>the predefined &c-lang; types (&ctype-r;)</title>
<varlistentry id="simple-c-type">
   <term><replaceable>simple-c-type</replaceable></term>
<listitem><para>the simple &c-lang; types
  <informaltable id="simple-c-type-tab" frame="all">
 <tgroup cols="5" colsep="1" rowsep="1" align="center">
 <thead><row><entry>Lisp name</entry><entry>Lisp equivalent</entry>
 <entry>&c-lang; equivalent</entry><entry>&ilu; equivalent</entry>
 <entry>Comment</entry></row></thead><tbody>
<row><entry>&nil;</entry><entry>&nil;</entry><entry><type>void</type></entry>
   <entry/><entry>as a result type only</entry></row>
<row><entry>&boolean-t;</entry><entry>&boolean-t;</entry>
   <entry>&int-t;</entry><entry><type>BOOLEAN</type></entry></row>
<row><entry>&character-t;</entry><entry>&character-t;</entry>
   <entry><type>char</type></entry>
   <entry><type>SHORT CHARACTER</type></entry></row>
<row><entry><type>char</type></entry><entry>&integer-t;</entry>
   <entry><type>signed char</type></entry></row>
<row><entry><type>uchar</type></entry><entry>&integer-t;</entry>
   <entry><type>unsigned char</type></entry></row>
<row><entry><type>short</type></entry><entry>&integer-t;</entry>
   <entry><type>short</type></entry></row>
<row><entry><type>ushort</type></entry><entry>&integer-t;</entry>
   <entry><type>unsigned short</type></entry></row>
<row><entry>&int-t;</entry><entry>&integer-t;</entry>
   <entry>&int-t;</entry></row>
<row><entry><type>uint</type></entry><entry>&integer-t;</entry>
   <entry><type>unsigned int</type></entry></row>
<row><entry><type>long</type></entry><entry>&integer-t;</entry>
   <entry><type>long</type></entry></row>
<row><entry><type>ulong</type></entry><entry>&integer-t;</entry>
   <entry><type>unsigned long</type></entry></row>
<row><entry><type>uint8</type></entry><entry>&ubyte-8;</entry>
   <entry><type>uint8</type></entry><entry><type>BYTE</type></entry></row>
<row><entry><type>sint8</type></entry><entry>&sbyte-8;</entry>
   <entry><type>sint8</type></entry></row>
<row><entry><type>uint16</type></entry><entry>&ubyte-16;</entry>
   <entry><type>uint16</type></entry>
   <entry><type>SHORT CARDINAL</type></entry></row>
<row><entry><type>sint16</type></entry><entry>&sbyte-16;</entry>
   <entry><type>sint16</type></entry>
   <entry><type>SHORT INTEGER</type></entry></row>
<row><entry><type>uint32</type></entry><entry>&ubyte-32;</entry>
   <entry><type>uint32</type></entry><entry><type>CARDINAL</type></entry></row>
<row><entry><type>sint32</type></entry><entry>&sbyte-32;</entry>
   <entry><type>sint32</type></entry><entry><type>INTEGER</type></entry></row>
<row><entry><type>uint64</type></entry>
   <entry><literal role="type">(&unsigned-byte-t; 64)</literal></entry>
   <entry><type>uint64</type></entry><entry><type>LONG CARDINAL</type></entry>
   <entry>does not work on all platforms</entry></row>
<row><entry><type>sint64</type></entry>
   <entry><literal role="type">(&signed-byte-t; 64)</literal></entry>
   <entry><type>sint64</type></entry><entry><type>LONG INTEGER</type></entry>
   <entry>does not work on all platforms</entry></row>
<row><entry>&single-float-t;</entry><entry>&single-float-t;</entry>
   <entry><type>float</type></entry></row>
<row><entry>&double-float-t;</entry><entry>&double-float-t;</entry>
   <entry><type>double</type></entry></row>
</tbody></tgroup></informaltable></para></listitem></varlistentry>

<varlistentry id="c-pointer"><term>&c-pointer;</term>
 <listitem><simpara>This type corresponds to what &c-lang; calls
   <type>void*</type>, an opaque pointer.
   When used as an argument, &nil; is accepted as a &c-pointer; and
   treated as &c-NULL;; when a function wants to return a &c-NULL;
   &c-pointer;, it actually returns &nil;.
</simpara></listitem></varlistentry>

<varlistentry><term><literal role="type">(&c-pointer;
  &ctype-r;)</literal></term>
 <listitem><simpara>This type is equivalent to what &c-lang; calls
  <type>&ctype-r; *</type>: a pointer to a single item of the given
  &ctype-r;. It differs from <literal role="type">(&c-ptr-null;
  &ctype-r;)</literal> (see below) in that no conversion to and from
  Lisp will occur (beyond the usual one of the &c-lang; &c-NULL; pointer
  to or from Lisp &nil;). Instead, an object of type &foreign-variable-t;
  is used to represent the foreign &place;. It is assimilable to a typed
  pointer.</simpara></listitem></varlistentry>

<varlistentry id="c-string"><term>&c-string;</term>
 <listitem><simpara>This type corresponds to what &c-lang; calls
  <type>char*</type>, a zero-terminated string.  Its Lisp equivalent is
  a string, without the trailing zero character.
 </simpara></listitem></varlistentry>

<varlistentry id="c-struct"><term><literal role="type">(&c-struct; &class-r;
   (&ident1-r; &ctype1-r;) ... (&identn-r; &ctypen-r;))</literal></term>
 <listitem><simpara>This type is equivalent to what &c-lang; calls
   <type>struct { &ctype1-r; &ident1-r;; ...; &ctypen-r; &identn-r;; }</type>.
   Its Lisp equivalent is: if &class-r; is &vector-t;, a
   &simple-vector-t;; if &class-r; is &list-t;, a &proper-list-glo;;
   if &class-r; is a symbol naming a structure or &clos; class, an
   instance of this class, with slots of names
   &ident1-r;, ..., &identn-r;.</simpara><simpara>
   &class-r; may also be a &cons-t; of a &symbol-t; (as above) and
   a &list-t; of &def-c-struct; options.
</simpara></listitem></varlistentry>

<varlistentry id="c-union"><term><literal role="type">(&c-union;
   (&ident1-r; &ctype1-r;) ... (&identn-r; &ctypen-r;))</literal></term>
 <listitem><simpara>This type is equivalent to what &c-lang; calls
   <type>union { &ctype1-r; &ident1-r;; ...; &ctypen-r; &identn-r;; }</type>.
   Conversion to and from Lisp assumes that a value is to be viewed as
   being of &ctype1-r;.
</simpara></listitem></varlistentry>

<varlistentry id="c-array"><term><literal role="type">(&c-array;
   &ctype-r; &dim1-r;)</literal></term>
 <term><literal role="type">(&c-array; &ctype-r; (&dim1-r;
   ... &dimn-r;))</literal></term>
 <listitem><simpara>This type is equivalent to what &c-lang; calls
   <type>&ctype-r; [&dim1-r;] ... [&dimn-r;]</type>.
   Note that when an array is passed as an argument to a function in
   &c-lang;, it is actually passed as a pointer; you therefore have to
   write <literal role="type">(&c-ptr; (&c-array; ...))</literal> for this
   argument's type.</simpara></listitem></varlistentry>

<varlistentry id="c-array-max"><term><literal role="type">(&c-array-max;
   &ctype-r; &maxdim-r;)</literal></term>
 <listitem><simpara>This type is equivalent to what &c-lang; calls
   <type>&ctype-r; [&maxdim-r;]</type>, an array containing up to
   &maxdim-r; elements.
   The array is zero-terminated if it contains less than &maxdim-r; elements.
   Conversion from Lisp of an array with more than &maxdim-r; elements
   silently ignores the extra elements.
</simpara></listitem></varlistentry>

<varlistentry id="c-function"><term><literal
   role="type">(&c-function; (&arguments-k;
      {(&arg-r; <replaceable>a-c-type</replaceable>
        [&param-mode; [&allocation;]])}*)
    (&ret-type-k; <replaceable>r-c-type</replaceable> [&allocation;])
    (&lang-k; &lang-r;))</literal></term>
 <listitem><simpara>This type designates a &c-lang; function that can be
  called according to the given prototype
   <code>(<replaceable>r-c-type</replaceable> (*)
    (<replaceable>a-c-type&sub-1;</replaceable>, ...))</code>.
  Conversion between &c-lang; functions and Lisp functions
  is transparent, and &c-NULL;/&nil; is recognized and
  accepted.</simpara></listitem></varlistentry>

<varlistentry id="c-ptr">
 <term><literal role="type">(&c-ptr; &ctype-r;)</literal></term>
 <listitem><simpara>This type is equivalent to what &c-lang; calls
   <type>&ctype-r; *</type>: a pointer to a single item of the given
   &ctype-r;.</simpara></listitem></varlistentry>

<varlistentry id="c-ptr-null">
 <term><literal role="type">(&c-ptr-null; &ctype-r;)</literal></term>
 <listitem><simpara>This type is also equivalent to what &c-lang; calls
   <type>&ctype-r; *</type>: a pointer to a single item of the given
   &ctype-r;, with the exception that &c-lang; &c-NULL; corresponds to
   Lisp &nil;.</simpara></listitem></varlistentry>

<varlistentry id="c-array-ptr">
 <term><literal role="type">(&c-array-ptr; &ctype-r;)</literal></term>
 <listitem><simpara>This type is equivalent to what &c-lang; calls
   <type>&ctype-r; (*)[]</type>: a pointer to a zero-terminated array of
   items of the given &ctype-r;.</simpara></listitem></varlistentry>
</variablelist>

<!-- #ifdef ENABLE_UNICODE -->
<para>The conversion of &c-string;,
 <literal role="type">(&c-array; &character-t; &dim1-r;)</literal>,
 <literal role="type">(&c-array-max; &character-t; &maxdim-r;)</literal>,
 <literal role="type">(&c-array-ptr; &character-t;)</literal>
 is governed by &foreign-enc; and dimensions are given
 in <emphasis>bytes</emphasis>.
 The conversion of &character-t;, and as such of
 <literal role="type">(&c-ptr; &character-t;)</literal>, or
 <literal role="type">(&c-ptr-null; &character-t;)</literal>, as well as
 that of multi-dimensional arrays <literal role="type">(&c-array; &character-t;
 (&dim1-r; ... &dimn-r;))</literal>, are governed by &foreign-enc; if
 the latter is a &enc1-1;, or by the &ascii; encoding otherwise.</para>
<!-- #endif -->
<note><para>Remember that the &c-lang; type <type>char</type> is
  a <emphasis>numeric</emphasis> type and does not use &character-t;
  &encoding;s.</para></note>

</section>

<section id="c-flavor"><title>The choice of the &c-lang; flavor</title>

<para>&c-function;, &def-call-in;, &def-call-out; take a &lang-k; argument.
The &lang-r; is either &c-k; (denotes K&amp;R &c-lang;) or &stdc-k;
(denotes &the-ansi; &c-lang;) or &stdc-sc-k; (denotes &the-ansi; &c-lang;
with the <ulink url="google">stdcall</ulink> calling convention).
It specifies whether the &c-lang; function (caller or callee) has been
compiled by a K&amp;R &c-lang; compiler or by an &the-ansi; &c-lang; compiler,
and possibly the calling convention.</para>

<para>The default language is set using the macro
 <firstterm>&default-foreign-language;
  <indexterm id="dflt-ffi-lang" significance="preferred">
   <primary><function>DEFAULT-FOREIGN-LANGUAGE</function>
 </primary></indexterm></firstterm>.
 If this macro has not been called in the current &comp-unit;
 (usually a file), a warning is issued and &stdc-k; is used for the rest
 of the unit.</para></section>

<section id="dffi-variables"><title>Foreign variables</title>

<para><firstterm>Foreign variables<indexterm id="dffi-fv"><primary>foreign
    variable</primary></indexterm></firstterm> are variables whose
 storage is allocated in the foreign language module.
 They can nevertheless be evaluated and modified through &setq;,
 just as normal variables can, except that the range of allowed values
 is limited according to the variable's foreign type.</para>

<warning id="dffi-eq"><title>Equality of foreign values</title>
 <simpara>For a foreign variable &x-r; the form <code>(&eql; &x-r;
   &x-r;)</code> is not necessarily true, since every time &x-r; is
  evaluated its foreign value is converted to a &fresh; Lisp value.
  Ergo, <code>(&setf; (&aref; &x-r; &n-r;) &y-r;)</code> modifies this
  &fresh; Lisp value (immediately discarded), &not-e; the foreign data.
  Use &element; et al instead, see <xref linkend="dffi-places"/>.
</simpara></warning>

<para>Foreign variables are defined using &def-c-var; and &with-c-var;.</para>

</section>

<section id="dffi-places"><title>Operations on foreign places</title>

<para>A &foreign-variable-t; &name-r; defined by &def-c-var;, &with-c-var;
 or &with-c-place; defines a &place;,
 i.e., a form which can also be used as argument to &setf;.
 (An <quote role="dict">lvalue</quote> in &c-lang; terminology.)
 The following operations are available on foreign places:
 <simplelist columns="2"><member>&element;</member><member>&deref;</member>
  <member>&slot;</member><member>&cast;</member><member>&offset;</member>
  <member>&c-var-addr;</member><member>&c-var-object;</member>
  <member>&typeof;</member><member>&sizeof;</member>
  <member>&bitsizeof;</member></simplelist></para>

</section>

<section id="dffi-functions"><title>Foreign functions</title>

<para>Foreign functions are functions which are defined in the foreign language.
 There are <firstterm>named foreign functions<indexterm id="dffi-ff-n">
   <primary>foreign function</primary><secondary>named</secondary>
 </indexterm></firstterm>
 (imported via &def-call-out; or created via &def-call-in;) and
 <firstterm>anonymous foreign functions<indexterm id="dffi-ff-a">
   <primary>foreign function</primary><secondary>anonymous</secondary>
 </indexterm></firstterm>; they arise through conversion of function
 pointers using &foreign-function;.</para>

<para>A <firstterm>call-out function<indexterm id="dffi-ff-call-out">
   <primary>foreign function</primary><secondary>call-out</secondary>
 </indexterm></firstterm> is a foreign function
 called from Lisp: control flow temporarily leaves Lisp.
 A <firstterm>call-in function<indexterm id="dffi-ff-call-in">
   <primary>foreign function</primary><secondary>call-in</secondary>
 </indexterm></firstterm>
 (AKA <firstterm>callback<indexterm id="def-call-in-callback-main" significance="preferred"><primary>callback</primary></indexterm></firstterm>)
 is a Lisp function called from the foreign language:
 control flow temporary enters Lisp.</para>

<para>The following operators define foreign functions:
 <simplelist columns="1"><member>&def-call-in;</member>
  <member>&def-call-out;</member><member>&foreign-function;</member>
</simplelist></para>

<section id="dffi-callback-mem">
 <title>Callbacks and memory management</title>
<para>Callbacks (&c-lang; function calling Lisp function) create
 so-called <firstterm>trampolines<indexterm id="dffi-trampoline">
   <primary>trampoline</primary></indexterm></firstterm>.
 A trampoline is a piece of &c-lang; code which knows how to call a
 particular Lisp function.
 (That is how all foreign language interfaces work, not just ours).
 The &c-lang; pointer that the foreign library receives is the pointer
 to this piece of code.
 These are &not-e; subject to &gc;ion, as there is no protocol to
 tell the garbage collector when a given callback is not needed anymore
 (unlike with Lisp objects).</para>
<para>With callbacks to <emphasis>named</emphasis> functions (i.e.,
 created by a &def-call-in; form where &func-r; is a &funname;) this is
 mostly harmless, since &func-r; is unlikely to be redefined.</para>
<para>With callbacks to <emphasis>anonymous</emphasis> functions (i.e.,
 created by &foreign-function; or a &def-call-in; form where &func-r;
 argument is a &lambda-expr;), this might become an issue when they are
 produced dynamically and en masse, e.g. inside a loop, so that many
 trampolines are generated.</para>
<para>You can use &foreign-free; to free the trampoline associated with a
 &foreign-function-t; object, but when you pass a &lambda-expr; to a
 &def-call-out; as an argument of type &c-function;, such a trampoline
 &is-e; allocated, but you do &not-e; get hold of the associated trampoline
 object, and thus you cannot (trivially) free it.
 Thus you may find it easier to create the &foreign-function-t; object
 first, pass it to the &def-call-out;, and then call &foreign-free;
 manually.</para></section>

</section>

<section id="allocation"><title>Argument and result passing conventions</title>

<para>When passed to and from functions, allocation of arguments and
 results is handled as follows:</para>

<para>Values of &simple-c-type;, &c-pointer; are passed on the stack,
 with dynamic extent. The &allocation; is effectively ignored.</para>

<para>Values of type &c-string;, &c-ptr;, &c-ptr-null;, &c-array-ptr;
 need storage.  The &allocation; specifies the allocation policy:
<variablelist>
<varlistentry><term>&none-k;</term>
 <listitem><simpara>no storage is allocated.
</simpara></listitem></varlistentry>
<varlistentry><term>&alloca-k;</term>
 <listitem><simpara>allocation of storage on the stack, which has
   dynamic extent.</simpara></listitem></varlistentry>
<varlistentry><term>&malloc-free-k;</term>
 <listitem><simpara>storage will be allocated via &malloc; and released via
   &free;.</simpara></listitem></varlistentry></variablelist></para>

<para>If no &allocation; is specified, the default &allocation; is
 &none-k; for most types, but &alloca-k; for &c-string; and &c-ptr; and
 &c-ptr-null; and &c-array-ptr; and for &out-k; arguments.
 The &malloc-free-k; policy provides the ability to pass
 arbitrarily nested structures within a single conversion.</para>

<formalpara id="dffi-allocation-out"><title>Call-out function arguments:</title>
<para><variablelist>
 <varlistentry><term>For arguments passed from Lisp to &c-lang;:</term>
  <listitem><variablelist>
   <varlistentry><term>&malloc-free-k;</term>
    <listitem><simpara>Lisp allocates the storage using &malloc; and
     never deallocates it.  The &c-lang; function is supposed to call
     &free; when done with it.</simpara></listitem></varlistentry>
   <varlistentry><term>&alloca-k;</term>
    <listitem><simpara>Lisp allocates the storage on the stack, with
     dynamic extent.  It is freed when the &c-lang; function returns.
    </simpara></listitem></varlistentry>
   <varlistentry><term>&none-k;</term>
    <listitem><simpara>Lisp assumes that the pointer already points to a
     valid area of the proper size and puts the result value there.</simpara>
     <simpara>This is dangerous and deprecated.</simpara>
    </listitem></varlistentry></variablelist>
  </listitem></varlistentry>
 <varlistentry><term>For results passed from &c-lang; to Lisp:</term>
  <listitem><variablelist>
   <varlistentry><term>&malloc-free-k;</term>
    <listitem><simpara>Lisp calls &free; on it when done.
    </simpara></listitem></varlistentry>
   <varlistentry><term>&none-k;</term>
    <listitem><simpara>Lisp does nothing.
    </simpara></listitem></varlistentry></variablelist>
  </listitem></varlistentry></variablelist></para></formalpara>
<formalpara id="dffi-allocation-in"><title>Call-in function arguments:</title>
 <para><variablelist>
  <varlistentry><term>For arguments passed from &c-lang; to Lisp:</term>
   <listitem><variablelist>
    <varlistentry><term>&malloc-free-k;</term>
     <listitem><simpara>Lisp calls &free; on it when done.
     </simpara></listitem></varlistentry>
    <varlistentry><term>&alloca-k;</term><term>&none-k;</term>
     <listitem><simpara>Lisp does nothing.
     </simpara></listitem></varlistentry></variablelist>
   </listitem></varlistentry>
  <varlistentry><term>For results passed from Lisp to &c-lang;:</term>
   <listitem><variablelist>
    <varlistentry><term>&malloc-free-k;</term>
     <listitem><simpara>Lisp allocates the storage using &malloc; and
      never deallocates it.  The &c-lang; function is supposed to call
      &free; when done with it.</simpara></listitem></varlistentry>
   <varlistentry><term>&none-k;</term>
    <listitem><simpara>Lisp assumes that the pointer already points to a
     valid area of the proper size and puts the result value there.</simpara>
     <simpara>This is dangerous and deprecated.</simpara>
    </listitem></varlistentry></variablelist>
 </listitem></varlistentry></variablelist></para></formalpara>

<warning id="ffi-struct-arg"><simpara>Passing &c-struct;, &c-union;,
  &c-array;, &c-array-max; values as arguments (not via pointers) is
  only possible to the extent the &c-lang; compiler supports it.
  Most &c-lang; compilers do it right, but some &c-lang; compilers
  (such as &gcc; on <emphasis role="platform">hppa</emphasis>,
  <emphasis role="platform">x86_64</emphasis> and &win32;)
  have problems with this.
  The recommended workaround is to pass pointers; this is fully supported.
  See also <ulink url="ml">clisp-devel</ulink>
  (<ulink role="sfmail" url="200307141526.26925.bruno%40clisp.org"/>/<ulink role="gmane" url="devel/10089"/>).</simpara></warning>

</section>

<section id="param-mode"><title>Parameter Mode</title>

<para>A function parameter's &param-mode; may be</para>

<variablelist>
 <varlistentry><term>&in-k; (means: read-only):</term>
  <listitem><simpara>The caller passes information to the callee.
  </simpara></listitem></varlistentry>
 <varlistentry><term>&out-k; (means: write-only):</term>
  <listitem><simpara>The callee passes information back to the caller on
   return.  When viewed as a Lisp function, there is no Lisp argument
   corresponding to this, instead it means an additional return value.
   Requires &allocation; = &alloca-k;.</simpara></listitem></varlistentry>
 <varlistentry><term>&in-out-k; (means: read-write):</term>
  <listitem><simpara>Information is passed from the caller to the callee
   and then back to the caller.  When viewed as a Lisp function, the
   &out-k; value is returned as an additional return value.
  </simpara></listitem></varlistentry>
</variablelist>

<para>The default is &in-k;.</para>

</section>

<section id="dffi-examples"><title>Examples</title>

<example id="dffi-simple"><title>Simple declarations and access</title>

<para>The &c-lang; declaration <programlisting language="C">
struct foo {
  int a;
  struct foo * b[100];
};
</programlisting> corresponds to <programlisting language="lisp">
(&def-c-struct; foo
  (a int)
  (b (c-array (c-ptr foo) 100)))
</programlisting></para>

<para>The element access <programlisting language="C">
struct foo f;
f.b[7].a
</programlisting> corresponds to <programlisting language="lisp">
(declare (type foo f))
(foo-a (aref (foo-b f) 7)) <lineannotation>or</lineannotation>
(slot-value (aref (slot-value f 'b) 7) 'a)
</programlisting></para></example>

<example id="dffi-extern-var">
 <title>External &c-lang; variable and some accesses</title>

<para><programlisting language="C">
struct bar {
  short x, y;
  char a, b;
  int z;
  struct bar * n;
};

extern struct bar * my_struct;

my_struct-&gt;x++;
my_struct-&gt;a = 5;
my_struct = my_struct-&gt;n;
</programlisting> corresponds to <programlisting language="lisp">
(&def-c-struct; bar
  (x short)
  (y short)
  (a char)
  (b char) <lineannotation>or (b character) if it represents a character, not a number</lineannotation>
  (z int)
  (n (c-ptr bar)))

(&def-c-var; my_struct (:type (c-ptr bar)))

(setq my_struct (let ((s my_struct)) (incf (slot-value s 'x)) s)) <lineannotation>or</lineannotation>
(incf (slot my_struct 'x))
(setq my_struct (let ((s my_struct)) (setf (slot-value s 'a) 5) s)) <lineannotation>or</lineannotation>
(setf (slot my_struct 'a) 5)
(setq my_struct (slot-value my_struct 'n)) <lineannotation>or</lineannotation>
(setq my_struct (deref (slot my_struct 'n)))
</programlisting></para></example>

<example id="dffi-extern-func1"><title>Calling an external function</title>

<para>On &the-ansi; &c-lang; systems, <filename role="unix">stdlib.h</filename>
 contains the declarations:

<programlisting language="C">
typedef struct {
  int quot;   /* Quotient */
  int rem;    /* Remainder */
} div_t;
extern div_t div (int numer, int denom);
</programlisting>

This translates to

<programlisting language="lisp">
(&def-c-struct; (div_t :typedef)
  (quot int)
  (rem int))
(&default-foreign-language; :stdc)
(&def-call-out; div (&arguments-k; (numer int) (denom int))
  (&ret-type-k; div_t))
</programlisting>
Sample call from within Lisp (after running &clisp-link;):
<programlisting language="lisp">
(div 20 3)
<computeroutput>#S(DIV_T :QUOT 6 :REM 2)</computeroutput>
</programlisting></para></example>

<example id="dffi-extern-func2">
 <title>Another example for calling an external function</title>

<para>Suppose the following is defined in a file <filename>cfun.c</filename>:
<programlisting language="C">
struct cfunr { int x; char *s; };
struct cfunr * cfun (int i,char *s,struct cfunr * r,int a[10]) {
  int j;
  struct cfunr * r2;
  printf("i = %d\n", i);
  printf("s = %s\n", s);
  printf("r-&gt;x = %d\n", r-&gt;x);
  printf("r-&gt;s = %s\n", r-&gt;s);
  for (j = 0; j &lt; 10; j++) printf("a[%d] = %d.\n", j, a[j]);
  r2 = (struct cfunr *) malloc (sizeof (struct cfunr));
  r2-&gt;x = i+5;
  r2-&gt;s = "A C string";
  return r2;
}
</programlisting>

It is possible to call this function from Lisp using the file
<filename>callcfun.lisp</filename> (do not call it
<filename>cfun.lisp</filename> - &compile-file-my; will
<link linkend="c-file-overwrite">overwrite</link>
<filename>cfun.c</filename>) whose contents is:

<programlisting language="lisp">
(&defpackage; "TEST-C-CALL" (:use &cl-pac; &ffi-pac;))
(&in-package; "TEST-C-CALL")
(&eval-when; (compile) (setq &ffi-out-fun; t))
(&def-c-struct; cfunr (x int) (s c-string))
(&default-foreign-language; :stdc)
(&def-call-out; cfun (&ret-type-k; (c-ptr cfunr))
  (&arguments-k; (i int)
              (s c-string)
              (r (c-ptr cfunr) :in :alloca)
              (a (c-ptr (c-array int 10)) :in :alloca)))
(defun call-cfun ()
  (cfun 5 "A Lisp string" (make-cfunr :x 10 :s "Another Lisp string")
        '#(0 1 2 3 4 5 6 7 8 9)))
</programlisting>

Use the &module; facility:

<screen>
&sh-prompt; &clisp-link; create cfun callcfun.c
&sh-prompt; cc -O -c cfun.c
&sh-prompt; cd cfun
&sh-prompt; ln -s ../cfun.o cfun.o
Add cfun.o to NEW_LIBS and NEW_FILES in &link-sh;.
&sh-prompt; cd ..
&sh-prompt; base/lisp.run &opt-M; base/lispinit.mem &opt-c; callcfun.lisp
&sh-prompt; &clisp-link; add base base+cfun cfun
&sh-prompt; base+cfun/lisp.run &opt-M; base+cfun/lispinit.mem &opt-i; callcfun
&gt; (test-c-call::call-cfun)
i = 5
s = A Lisp string
r-&gt;x = 10
r-&gt;s = Another Lisp string
a[0] = 0.
a[1] = 1.
a[2] = 2.
a[3] = 3.
a[4] = 4.
a[5] = 5.
a[6] = 6.
a[7] = 7.
a[8] = 8.
a[9] = 9.
#S(TEST-C-CALL::CFUNR :X 10 :S "A C string")
&gt;
&sh-prompt; rm -r base+cfun</screen></para>

<para>Note that there is a memory leak here: The return value
<varname>r2</varname> of <function>cfun()</function> is
&malloc;ed but never &free;d. Specifying<programlisting language="lisp">
(&ret-type-k; (c-ptr cfunr) :malloc-free)
</programlisting>
is not an alternative because this would also
<function>free(r2-&gt;x)</function> but <varname>r2-&gt;x</varname> is a
pointer to static data.</para>

<para>The memory leak can be avoided using
<programlisting language="lisp">
(&ret-type-k; (c-pointer cfunr))
</programlisting>
instead, in conjunction with
<programlisting language="lisp">
(defun call-cfun ()
  (let ((data (cfun ...)))
    (&unwind-protect; (&foreign-value; data)
      (&foreign-free; data :FULL nil))))
</programlisting></para></example>

<example id="dffi-ex-macro"><title>Accessing &cpp; macros</title>
<para>Suppose you are interfacing to a library <filename>mylib.so</filename>
 which defines types, macros and <literal>inline</literal> functions
 in <filename>mylib.h</filename>:<programlisting language="C">
#define FOO(x)  .....
#define BAR ...
struct zot { ... }
inline int bar (int x) { ... }
</programlisting>
 To make them available from &clisp;, write these forms into the lisp
 file <filename>my.lisp</filename>:<programlisting language="lisp">
(&c-lines; "#include &lt;mylib.h&gt;
int my_foo (int x) { return FOO(x); }
int my_bar (int x) { return bar(x); }~%")
(&def-c-const; bar)
(&def-c-const; zot-size (:name "sizeof(struct zot)") (:guard nil))
(&def-call-out; my-foo (&name-k; "my_foo") (&arguments-k; (x ffi:int)) (&ret-type-k; ffi:int))
(&def-call-out; my-bar (&name-k; "my_bar") (&arguments-k; (x ffi:int)) (&ret-type-k; ffi:int))
</programlisting></para>
<para>Compiling this file will produce <filename>my.c</filename>
 and <filename>my.fas</filename> and you have two options:
 <orderedlist><listitem><para>Compile <filename>my.c</filename>
    into <filename>my.o</filename> with
    <screen>&sh-prompt; gcc -c my.c -lmylib</screen>
    and use &clisp-link; to create a new &clisp; &linkset;.
  </para></listitem>
  <listitem><para>Add <code>(&library-k; "my.dll")</code> to the &def-call-out;
    forms, compile <filename>my.c</filename> into <filename>my.so</filename>
    (or <filename>my.dll</filename> on &win32;) with
    <screen>&sh-prompt; gcc -shared -o my.so my.c -lmylib</screen> and
    load <filename>my.fas</filename>.</para></listitem></orderedlist></para>
<para>Of course, you could have created <filename>my1.c</filename>
 containing<programlisting language="C">
#include &lt;mylib.h&gt;
int my_foo (int x) { return FOO(x); }
int my_bar (int x) { return bar(x); }
</programlisting>manually, but &c-lines; allows you to keep the
 definitions of <function>my_foo</function> and <function>my-foo</function>
 close together for easier maintenance.</para>
</example>

<example id="ex-call-in"><title>Calling Lisp from &c-lang;</title>

<para>To sort an array of double-floats using the Lisp function &sort;
 instead of the &c-lang; library function
 <function role="unix">qsort</function>, one can use the
 following interface code <filename>sort1.c</filename>.
 The main problem is to pass a variable-sized array.

<programlisting language="C">
extern void lispsort_begin (int);
void* lispsort_function;
void lispsort_double (int n, double * array) {
  double * sorted_array;
  int i;
  lispsort_begin(n); /* store #'sort2 in lispsort_function */
  sorted_array = ((double * (*) (double *)) lispsort_function) (array);
  for (i = 0; i &lt; n; i++) array[i] = sorted_array[i];
  free(sorted_array);
}
</programlisting>

This is accompanied by <filename>sort2.lisp</filename>:

<programlisting language="lisp">
(&defpackage; "FFI-TEST" (:use &cl-pac; &ffi-pac;))
(&in-package; "FFI-TEST")
(&eval-when; (compile) (&setq; &ffi-out-fun; t))
(&def-call-in; lispsort_begin (&arguments-k; (n int))
  (&ret-type-k; nil)
  (&lang-k; :stdc))
(&def-c-var; lispsort_function (:type c-pointer))
(&defun; lispsort_begin (n)
  (&setf; (&cast; lispsort_function
              `(&c-function;
                 (&arguments-k; (v (c-ptr (c-array double-float ,n))))
                 (&ret-type-k; (c-ptr (c-array double-float ,n))
                               :malloc-free)))
        #'sort2))
(&defun; sort2 (v)
  (declare (type vector v))
  (sort v #'&lt;))
</programlisting>

To test this, use the following test file <filename>sorttest.lisp</filename>:

<programlisting language="lisp">
(&eval-when; (compile) (setq &ffi-out-fun; t))
(&def-call-out; sort10
  (&name-k; "lispsort_double")
  (&lang-k; :stdc)
  (&arguments-k; (n int)
              (array (c-ptr (c-array double-float 10)) :in-out)))
</programlisting>

Now try

<screen>&sh-prompt; &clisp-link; create sort sort2.c sorttest.c
&sh-prompt; cc -O -c sort1.c
&sh-prompt; cd sort
&sh-prompt; ln -s ../sort1.o sort1.o</screen>

Add <filename>sort1.o</filename> to <envar>NEW_LIBS</envar>
and <envar>NEW_FILES</envar> in &link-sh;.
Create a file <filename>package.lisp</filename> containing the form
<programlisting language="lisp">
(&make-package; "FFI-TEST" :use '(&cl-pac; &ffi-pac;))</programlisting>
and add <filename>package.lisp</filename> to &mod-preload; in &link-sh;.
Proceed:

<screen>&sh-prompt; cd ..
&sh-prompt; base/lisp.run &opt-M; base/lispinit.mem &opt-c; sort2.lisp sorttest.lisp
&sh-prompt; &clisp-link; add base base+sort sort
&sh-prompt; base+sort/lisp.run &opt-M; base+sort/lispinit.mem &opt-i; sort2 sorttest
&gt; (sort10 10 '#(0.501d0 0.528d0 0.615d0 0.550d0 0.711d0
                0.523d0 0.585d0 0.670d0 0.271d0 0.063d0))
#(0.063d0 0.271d0 0.501d0 0.523d0 0.528d0 0.55d0 0.585d0 0.615d0 0.67d0 0.711d0)
&sh-prompt; rm -r base+sort</screen></para></example>

<example id="ex-call-in-dll">
 <title>Calling Lisp from &c-lang; dynamically</title>

<para>Create a dynamic library <filename>lispdll</filename>
 (<filename>#P".dll"</filename> on &win32;,
  <filename>#P".so"</filename> on &unix;)
  with the following function:<programlisting language="C">
typedef int (*LispFunc)(int parameter);
int CallInFunc(LispFunc f) {
  return f(5)+11;
}
</programlisting>
  and call it from Lisp:
  <programlisting language="lisp">
(ffi:def-call-out callout
  (&name-k; "CallInFunc")
  (&library-k; "lispdll.dll")
  (&arguments-k; (function-arg
               (&c-function; (&arguments-k; (number ffi:int))
                               (&ret-type-k; ffi:int) (&lang-k; :stdc))))
  (&ret-type-k; ffi:int)
  (&lang-k; :stdc))
(defun f (x) (* x 2))
<computeroutput>F</computeroutput>
(callout #'f)
<computeroutput>21</computeroutput>
</programlisting></para></example>

<example id="dffi-gethostname"><title>Variable size arguments:
  calling <function role="unix">gethostname</function> from &clisp;</title>

<para>The standard &unix; function
 <funcsynopsis id="gethostname-synopsis"><funcprototype>
   <funcdef>&int-t; <function>gethostname</function></funcdef>
   <paramdef><type>char*</type> <parameter>name</parameter></paramdef>
   <paramdef><type>size_t</type> <parameter>length</parameter></paramdef>
</funcprototype></funcsynopsis>
 follows a typical pattern of &c-lang; <quote>out</quote>-parameter
 convention: it expects a pointer to a buffer it is going to fill.
 So you must view this parameter as either &out-k; or &in-out-k;.
 Additionally, one must tell the function the size of the buffer.
 Here &len-r; is just an &in-k; parameter.
 Sometimes this will be an &in-out-k; parameter, returning the
 number of bytes actually filled in.</para>

<para>So &name-r; is actually a pointer to an array of up to &len-r;
 characters, regardless of what the poor <type>char*</type> &c-lang;
 prototype says, to be used like a &c-lang; <type>string</type>
 (&c-NULL;-termination).  &unix; specifies that <quote>host names are
 limited to <constant>HOST_NAME_MAX</constant> bytes</quote>, which is,
 of course, system dependent, but it appears that 256 is sufficient.</para>

<para>In the present example, you can use allocation &alloca-k;, like
 you would do in &c-lang;: stack-allocate a temporary:
<programlisting language="lisp">
(&def-call-out; gethostname
  (&arguments-k; (name (&c-ptr; (&c-array-max; ffi:char 256))
                    &out-k; &alloca-k;)
              (length ffi:int))
  (&lang-k; :stdc) (&library-k; :default)
  (&ret-type-k; ffi:int))
<computeroutput>GETHOSTNAME</computeroutput>
(defun myhostname ()
  (multiple-value-bind (success name)<lineannotation>&out-k; and &in-out-k; parameters are returned as &mul-val;</lineannotation>
      (gethostname 256)
    (if (zerop success) name
      (error "~S: ~S: ~S" 'myhostname (os:errno) (os:strerror)))))<lineannotation>See <xref linkend="errno"/></lineannotation>
<computeroutput>MYHOSTNAME</computeroutput>
(myhostname)
<computeroutput>#(97 98 97 122 111 110 107)</computeroutput></programlisting>
It is a &simple-vector-t;, not a &string-t;, because the &name-r;
argument is an array of <type>char</type> (an &integer-t; type, see
<xref linkend="dffi-types"/>), &not-e; <type>character</type>.
<programlisting language="lisp">
(&def-call-out; gethostname
  (&arguments-k; (name (&c-ptr; (&c-array-max; character 256))
                    &out-k; &alloca-k;)
              (length ffi:int))
  (&lang-k; :stdc) (&library-k; :default)
  (&ret-type-k; ffi:int))
<computeroutput>GETHOSTNAME</computeroutput>
(myhostname)
<computeroutput>"abazonk"</computeroutput></programlisting>
Now we have a different problem:
if <function role="unix">gethostname</function> fails, then the buffer
allocated for &name-r; will be filled with garbage, but it will still go
through the string conversion &before-e; we can check
the <replaceable>success</replaceable> status.
If &foreign-enc; is &iso-8859-1;, this is not a problem since no real
conversion is happening, but with &utf-8; an &error-t; may be &signal;ed.
A safe approach is to pass to the foreign function our own
stack-allocated buffer, and only convert the buffer to a string when the
foreign function succeeds: <programlisting language="lisp">
(&def-call-out; gethostname
  (&arguments-k; (name &c-pointer;)
              (length ffi:int))
  (&lang-k; :stdc) (&library-k; :default)
  (&ret-type-k; ffi:int))
<computeroutput>GETHOSTNAME</computeroutput>
(defun myhostname ()
  (&with-foreign-object; (name '(&c-array-max; character 256))
    (let ((success (gethostname name 256)))
      (if (zerop success) (&foreign-value; name)
        (error "~S: ~S: ~S" 'myhostname (os:errno) (os:strerror))))))
<computeroutput>MYHOSTNAME</computeroutput>
(myhostname)
<computeroutput>"abazonk"</computeroutput></programlisting>
Note that the &type-r; argument of &with-foreign-object; is evaluated,
so we do not have to make any assumptions
about <constant>HOST_NAME_MAX</constant>: <programlisting language="lisp">
(defun myhostname ()
  (let ((host-name-max (<link linkend="sysinfo">os:sysconf</link> :host-name-max)))
    (&with-foreign-object; (name `(&c-array-max; character ,host-name-max))
      (let ((success (gethostname name host-name-max)))
        (if (zerop success) (&foreign-value; name)
          (error "~S: ~S: ~S" 'myhostname (os:errno) (os:strerror)))))))
<computeroutput>MYHOSTNAME</computeroutput>
(myhostname)
<computeroutput>"abazonk"</computeroutput></programlisting>
</para></example>

<example id="dffi-dll-var">
 <title>Accessing variables in shared libraries</title>

<para>Suppose one wants to access and modify variables that reside in
 shared libraries:
<programlisting language="C">
struct bar {
  double x, y;
  double out;
};

struct bar my_struct = {10.0, 20.5, 0.0};

double test_dll(struct bar *ptr)
{
  return ptr-&gt;out = ptr-&gt;out + ptr-&gt;x + ptr-&gt;y;
}
</programlisting></para>

<para>This is compiled to <filename>libtest.so</filename> (or
 <filename>libtest.dll</filename>, depending on your platform).</para>

<para>Use the following lisp code:
<programlisting language="lisp">
(&use-package; &ffi-pac;)

(&def-c-struct; bar
  (x double-float)
  (y double-float)
  (out double-float))

(&def-call-out; get-own-c-float
  (&library-k; "libtest.so")
  (&lang-k; :stdc)
  (&name-k; "test_dll")
  (&arguments-k; (ptr c-pointer :in :alloca))
  (&ret-type-k; double-float))

(&def-c-var; my-c-var (:name "my_struct")
  (&library-k; "libtest.so") (:type (c-ptr bar)))
</programlisting></para>

<para>Note that <function>get-own-c-float</function> takes a
 &c-pointer;, not a <literal role="type">(&c-ptr; bar)</literal> as the
 argument.</para>

<para>Now you can access call <function>get-own-c-float</function> on
<varname>my-c-var</varname>:
<programlisting language="lisp">
(&c-var-addr; my-c-var)
<computeroutput>#&lt;FOREIGN-ADDRESS #x282935D8&gt;</computeroutput>
(get-own-c-float (&c-var-addr; my-c-var))
<computeroutput>30.5d0</computeroutput>
(get-own-c-float (&c-var-addr; my-c-var))
<computeroutput>61.0d0</computeroutput>
(get-own-c-float (&c-var-addr; my-c-var))
<computeroutput>91.5d0</computeroutput>
(get-own-c-float (&c-var-addr; my-c-var))
<computeroutput>122.0d0</computeroutput>
</programlisting></para>

</example>

<example id="ex-dffi-validity"><title>Controlling validity of resources</title>

<para>&set-foreign-pointer; is useful in conjunction with <code>(&setf;
  &validp;)</code> to limit the extent of external resources.
 Closing twice can be avoided by checking &validp;.
 All pointers depending on this resource can be disabled at once upon
 close by sharing their &foreign-pointer; using &set-foreign-pointer;.
<programlisting language="lisp">
(&def-c-type; PGconn c-pointer)<lineannotation>opaque pointer</lineannotation>
(&def-call-out; PQconnectdb (&ret-type-k; PGconn)
  (&arguments-k; (conninfo c-string)))
(defun sql-connect (conninfo)
  (let ((conn (PQconnectdb conninfo)))
    (unless conn (error "NULL pointer"))
    ;; may wish to use &finalize; as well
    (&set-foreign-pointer; conn &copy-k;)))
(defun sql-dependent-resource (conn arg1)
  (&set-foreign-pointer; (PQxxx conn arg1) conn))
(defun sql-close (connection)
  (when (&validp; connection)
    (PQfinish connection)
    (setf (&validp; connection) nil)
    T))
</programlisting>
<warning><para>Sharing &foreign-pointer; goes both ways: invalidating
  the dependent resource will invalidate the primary one.</para></warning>
<note><para>An alternative approach to resource management,
  more suitable to non-&ffi-pac; &module;s,
  is implemented in the &berkeley-db-mod; module,
  see <xref linkend="bdb-close"/>.</para></note></para></example>

<example id="ex-dffi-float"><title>Floating point arrays</title>
<para>Save this code into <filename>sum.c</filename>:
<programlisting language="C">
double sum (int len, double *vec) {
  int i;
  double s=0;
  for (i=0; i&lt;len; i++) s+= vec[i];
  return s;
}
</programlisting>
and compile it with
<screen>&sh-prompt; gcc -shared -o libsum.so sum.c</screen>
Now you can sum doubles:
<programlisting language="lisp">
(&def-call-out; sum (&name-k; "sum") (&library-k; "libsum.so") (&lang-k; :stdc)
  (&ret-type-k; ffi:double-float)
  (&arguments-k; (len ffi:int) (vec (&c-array-ptr; ffi:double-float))))
(sum 3 #(1d0 2d0 3d0))
<computeroutput>6d0</computeroutput>
</programlisting></para></example>

<section id="dffi-ex-more"><title>More examples</title>

<para>You can find more information and examples of the &clisp;
 &ffi-pac; in the following <ulink url="ml">clisp-list</ulink> messages:
 <variablelist><varlistentry><term>variable size values</term>
   <listitem><simpara><ulink role="sfmail" url="9F8582E37B2EE5498E76392AEDDCD3FE05F4B8F7%40G8PQD.blf01.telekom.de"/>/<ulink role="gmane" url="general/7278"/>
  </simpara></listitem></varlistentry>
  <varlistentry><term>variable length arrays</term>
   <listitem><simpara><ulink role="sfmail" url="9F8582E37B2EE5498E76392AEDDCD3FE0287A252%40G8PQD.blf01.telekom.de"/>/<ulink role="gmane" url="general/6626"/>
     <ulink role="sfmail" url="9F8582E37B2EE5498E76392AEDDCD3FE0287A3B1%40G8PQD.blf01.telekom.de"/>/<ulink role="gmane" url="general/6628"/>
</simpara></listitem></varlistentry></variablelist></para>
<para>Even more examples can be found in the file
 <filename role="clisp-cvs">tests/ffi.tst</filename>
 in the &clisp; source distribution.</para>
</section>
</section>

</section>
<!-- #endif -->

<section id="socket"><title>Socket Streams</title>
<subtitle>&unix-w32-only;</subtitle>
<!-- #ifdef SOCKET_STREAMS -->

<section id="socket-intro"><title>Introduction</title>

<para><ulink url="http://www.freesoft.org/CIE/Topics/20.htm">Sockets</ulink>
 are used for interprocess communications by processes running on the
 same host as well as by processes running on different hosts over a
 computer network.
 The most common kind of sockets is Internet stream sockets, and a
 high-level interface to them is described here.
 A more low level interface that closely follows the &c-lang; system
 calls is also available, see <xref linkend="rawsock"/>.</para>

<para>Two main varieties of sockets are interfaced to:
 <variablelist><varlistentry><term><quote>active</quote> sockets</term>
   <listitem><simpara>correspond to &socket-stream;s which are &bidir-s;
     &stream-t;s</simpara></listitem></varlistentry>
  <varlistentry><term><quote>passive</quote> sockets</term>
   <listitem><simpara>correspond to &socket-server;s which are a special
     kind of objects that are used to allow the other side to initiate
     interaction with lisp.</simpara></listitem></varlistentry>
</variablelist></para>

<example id="socket-ex-server"><title>Lisp &repl; server</title>
<para>Here is a simple lisp &repl; server that waits for a remote
 connection and evaluates forms read from it:
<programlisting language="lisp">
(&let; ((server (&sose;)))
  (&format; t "~&amp;Waiting for a connection on ~S:~D~%"
          (&sose-host; server) (&sose-port; server))
  (&unwind-protect;
      ;; infinite loop, terminate with &ctrl-c;
      (&loop; (&with-open-stream; (socket (&so-accept; server))
              (&multiple-value-bind; (local-host local-port) (&sost-local; socket)
                (&multiple-value-bind; (remote-host remote-port) (&sost-peer; socket)
                  (&format; &t; "~&amp;Connection: ~S:~D -- ~S:~D~%"
                          remote-host remote-port local-host local-port)))
              ;; loop is terminated when the remote host closes the connection or on &exit;
              (&loop; (&when; (&eq; :eof (&so-status; (cons socket :input))) (&return;))
                    (&print; (&eval; (&read; socket)) socket)
                    ;; flush everything left in socket
                    (&loop; :for c = (&read-char-no-hang; socket nil nil) :while c)
                    (&terpri; socket))))
    ;; make sure server is closed
    (&sose-close; server)))
</programlisting>
<warning><title>This opens a gaping security hole!</title>
 <simpara>Functions like &shell;, &exec;, &run-cmd; will allow the
  remote host to execute arbitrary code with your permissions.
  While functions defined in lisp (like &run-cmd;) can be removed
  (using &fmakunbound;), the built-in functions (like &shell; and &exec;)
  cannot be permanently removed from the &rt;, and an experienced
  hacker will be able to invoke them even if you &fmakunbound; their names.
 </simpara><simpara>You should limit the socket server to local connections
  by passing the &string-t; <literal role="data">"127.0.0.1"</literal>
  as the <constant>:INTERFACE</constant> argument to &sose;.</simpara></warning>
</para></example>

<example id="socket-ex-client"><title>Lisp &http; client</title>
<para>Here are a couple of simple lisp &http; clients that fetch a web
 page and a binary file, and upload a file:
<programlisting language="lisp">
(&defun; wget-text (host page file &optional-amp; (port 80))
  ;; &http; requires the &dos-k; &line-term;
  (&with-open-stream; (socket (&so-connect; port host &extfmt; &dos-k;))
     (&format; socket "GET ~A HTTP/1.0~2%" page)
     ;; dump the whole thing - header+data - into the output file
     (&with-open-file; (out file :direction :output)
       (&loop; :for line = (&read-line; socket nil nil) :while line
          :do (&write-line; line out)))))
(&defun; wget-binary (host page file &optional-amp; (port 80))
  (&with-open-stream; (socket (&so-connect; port host &extfmt; &dos-k;))
    (&format; socket "GET ~A HTTP/1.0~2%" page)
    (&loop; :with content-length :for line = (&read-line; socket nil nil)
      ;; header is separated from the data with a blank line
      :until (&zerop; (&length; line)) :do
      (&when; (&string-eq; line #1="Content-length: " :end1 #2=&sharp-dot;(&length; #1#))
        (&setq; content-length (&parse-integer; line :start #2#))
      ;; this will not work if the server does not supply the content-length header
      :finally (&return; (&let; ((data (&make-array; content-length
                                               :element-type '&ubyte-8;)))
                           ;; switch to binary i/o on socket
                           (&setf; (&stream-element-type; socket) '&ubyte-8;)
                           ;; read the whole file in one system call
                           (&rd-by-seq; data socket)
                           (&with-open-file; (out file :direction :output
                                                &eltype; '&ubyte-8;)
                             ;; write the whole file in one system call
                             (&wr-by-seq; data out))
                           data))))))
(&defun; wput (host page file &optional-amp; (port 80))
  (&with-open-stream; (socket (&so-connect; port host &extfmt; &dos-k;))
    (&with-open-file; (in file :direction :inptut &eltype; '&ubyte-8;)
      (&let-star; ((length (&file-length; in))
             (data (&make-array; length :element-type '&ubyte-8;)))
        ;; some servers may not understand the "Content-length" header
        (&format; socket "PUT ~A HTTP/1.0~%Content-length: ~D~2%" page length)
        (&setf; (&stream-element-type; socket) '&ubyte-8;)
        (&rd-by-seq; data in)
        (&wr-by-seq; data socket)))
    ;; not necessary if the server understands the "Content-length" header
    (&sost-shut; socket :output)
    ;; get the server response
    (&loop; :for line = (&read-line; socket nil nil) :while line :collect line)))
</programlisting></para></example>
</section>

<section id="socket-api"><title>Socket API Reference</title>

 <variablelist>
  <varlistentry id="sose"><term><code>(&sose; &optional-amp; &port-r;
     &key-amp; <constant>:INTERFACE</constant>
     <constant>:BACKLOG</constant>)</code></term>
  <listitem><simpara>This function creates a passive socket an binds a
    port to it.  The server exists to watch for client connection
    attempts.</simpara>
   <simpara>The optional argument is the port to use (non-negative
    &fixnum-t;, &zero; means assigned by the system).</simpara>
   <simpara>The <constant>:BACKLOG</constant> parameter defines maximum
    length of queue of pending connections (see
    <function role="unix">listen</function>) and defaults to 1.</simpara>
   <simpara>The <constant>:INTERFACE</constant> parameter specifies the
    interface(s) on which the socket server will listen, and is either a
    &string-t;, interpreted as the interface &ip; address that will be
    bound, or a socket, from whose peer the connections will be made.</simpara>
   <simpara>Default is (for backward compatibility) to bind to all local
    interfaces, but for security reasons it is advisable to bind to
    the loopback interface <literal role="data">"127.0.0.1"</literal> if
    you need only local connections.</simpara></listitem></varlistentry>
 <varlistentry id="sose-close"><term><code>(&sose-close; &sose-r;)</code></term>
  <listitem><simpara>Closes down the server socket. <link linkend="close">Just
     like streams</link>, &socket-server;s are closed at &gc;ion.
    You should not rely on this however, because &gc;ion times are not
    deterministic and the port assigned to the server socket cannot be
    reused until it is closed.</simpara></listitem></varlistentry>
 <varlistentry id="sose-hopo"><term><code>(&sose-host; &sose-r;)</code></term>
  <term><code>(&sose-port; &sose-r;)</code></term>
  <listitem><simpara>Returns the host mask indicating which hosts can
    connect to this server and the port which was bound using &sose;.
 </simpara></listitem></varlistentry>
 <varlistentry id="so-wait"><term><code>(&so-wait;
    &sose-r; &timeout-opt;)</code></term>
  <listitem id="timeout-opt"><simpara>Wait for a fixed time for a
    connection on the &sose-r; (a &socket-server;).
    Without a timeout argument, &so-wait; blocks indefinitely.
    When timeout is zero, poll.
    Returns &t; when a connection is available (i.e., &so-accept; will
    not block) and &nil; on timeout.</simpara></listitem></varlistentry>
 <varlistentry id="so-accept"><term><code>(&so-accept; &sose-r;
    &key-amp; &eltype; &extfmt; &buffered; &timeout-k;)</code></term>
  <listitem><simpara>Waits for an attempt to connect to the &sose-r; and
   creates the server-side &bidir-s; &socket-stream; for the connection.
  </simpara><simpara>&sig-err; if no connection is made in that time.
  </simpara></listitem></varlistentry>
 <varlistentry id="so-connect"><term><code>(&so-connect;
    &port-r; &optional-amp; [&host-r;] &key-amp;
    &eltype; &extfmt; &buffered; &timeout-k;)</code></term>
  <listitem><simpara>Attempts to create a client-side &bidir-s;
   &socket-stream;.  Blocks until the server accepts the connection, for
   no more than &timeout-k; &seconds;.  If it is 0, returns immediately
   and (probably) blocks on the next i/o operation (you can use
   &so-status; to check whether it will actually block).
 </simpara></listitem></varlistentry>
 <varlistentry id="so-status"><term><code>(&so-status;
                 <replaceable>socket-stream-or-list</replaceable>
                 &timeout-opt;)</code></term>
  <listitem><simpara>Checks whether it is possible to read from or write
    to a &socket-stream; or whether a connection is available on a
    &socket-server; without blocking.</simpara>
   <simpara>This is similar to &listen;, which checks only one
    &stream-t; and only for input, and &so-wait;, which works only with
    &socket-server;s.</simpara>
   <simpara>We define &status-r; for a &socket-server; or a &socket-stream;
    to be &error-k; if &select; finds an exceptional condition pending
    on any of the argument &file-des;s.</simpara>
   <simpara>Additionally, for a &socket-server;, we define
    &status-r; to be &t; if a connection is available, i.e.,
    is &so-accept; will not block, and &nil; otherwise.</simpara>
   <para>Additionally, for a &socket-stream;, we define &status-r; in the
    given &direction-r; (one of &input-k;, &output-k;, and &io-k;) to be
    <variablelist id="so-status-values">&varlist-table;
     <title>Possible status values for various directions:</title>
     <varlistentry><term>&input-k; status:</term>
      <listitem><variablelist>&varlist-table;
        <varlistentry><term>&nil;</term>
         <listitem><simpara>reading will block
        </simpara></listitem></varlistentry>
        <varlistentry><term>&input-k;</term>
         <listitem><simpara>some input is available
        </simpara></listitem></varlistentry>
        <varlistentry><term>&eof-k;</term>
         <listitem><simpara>the stream has reached its end
       </simpara></listitem></varlistentry></variablelist>
     </listitem></varlistentry>
     <varlistentry><term>&output-k; status:</term>
      <listitem><variablelist>&varlist-table;
        <varlistentry><term>&nil;</term>
         <listitem><simpara>writing will block
        </simpara></listitem></varlistentry>
        <varlistentry><term>&output-k;</term>
         <listitem><simpara>output to the stream will not block
       </simpara></listitem></varlistentry></variablelist>
       </listitem></varlistentry>
     <varlistentry><term>&io-k; status:</term>
      <listitem><informaltable id="so-status-i-o" frame="all">
        <tgroup cols="4" colsep="1" rowsep="1" align="center">
         <colspec colname="out"/><colspec colname="nil"/>
         <colspec colname="inp"/><colspec colname="eof"/>
         <thead><row><entry morerows="1" valign="bottom">output status</entry>
           <entry namest="nil" nameend="eof">input status</entry></row>
          <row><entry>&nil;</entry><entry>&input-k;</entry>
           <entry>&eof-k;</entry></row></thead>
         <tbody><row><entry>&nil;</entry><entry>&nil;</entry>
           <entry>&input-k;</entry><entry>&eof-k;</entry></row>
          <row><entry>&output-k;</entry><entry>&output-k;</entry>
           <entry>&io-k;</entry><entry>&append-k;</entry></row></tbody>
      </tgroup></informaltable></listitem></varlistentry></variablelist></para>
   <variablelist><title>Possible values of
     <replaceable>socket-stream-or-list</replaceable>:</title>
    <varlistentry><term>&socket-stream; or &socket-server;</term>
     <listitem><simpara>Returns the appropriate status, as defined
       above (&io-k; status for &socket-stream;)
    </simpara></listitem></varlistentry>
    <varlistentry><term><code>(&socket-stream; . &direction-r;)</code></term>
     <listitem><simpara>Return the status in the specified direction
    </simpara></listitem></varlistentry>
    <varlistentry><term>a non-empty list of the above</term>
     <listitem><simpara>Return a list of values, one for each element of the
       argument list (a la &mapcar;)</simpara></listitem></varlistentry>
   </variablelist>
   <simpara>If you want to avoid &consing; up a &fresh; list, you can
    make the elements of <replaceable>socket-stream-or-list</replaceable>
    to be <literal role="data">(&sost-r; &direction-r; .
     &x-r;)</literal> or <literal role="data">(&sose-r; . &x-r;)</literal>.
    Then &so-status; will destructively modify its argument and replace
    &x-r; or &nil; with the status and return the modified list.
    You can pass this modified list to &so-status; again.</simpara>
   <simpara>The optional arguments specify the timeout. &nil; means
    wait forever, &zero; means poll.</simpara>
   <simpara>The second value returned is the number of objects with
    non-&nil; status, i.e., <quote>actionable</quote> objects.
    &so-status; returns either due to a timeout or when this number is
    positive, i.e., if the timeout was &nil; and &so-status; did
    return, then the second value is positive (this is the reason &nil;
    is &not-e; treated as an empty &list-t;, but as an invalid
    argument).</simpara>
   <simpara>This is the interface to &select;
    (on some platforms, <function role="unix">poll</function>),
    so it will work on any &clisp; &stream-t; which is based on a
    &file-des;, e.g., &kbd-in; and &file-pipe-socket-s;s, as well as
    on <link linkend="rawsock">raw sockets</link>.</simpara>
 </listitem></varlistentry>
 <varlistentry id="sost-hopo">
  <term><code>(&sost-host; &sost-r;)</code></term>
  <term><code>(&sost-port; &sost-r;)</code></term>
  <listitem><simpara>These two functions return information about the
    &socket-stream;.</simpara></listitem></varlistentry>
 <varlistentry id="sost-peer"><term><code>(&sost-peer;
    &sost-r; [<replaceable>do-not-resolve-p</replaceable>])</code></term>
  <listitem><simpara>Given a &socket-stream;, this function returns the
    name of the host on the opposite side of the connection and its port
    number; the server-side can use this to see who connected.</simpara>
   <simpara>When the optional second argument is non-&nil;, the hostname
    resolution is disabled and just the &ip; address is returned, without
    the <acronym>FQDN<alt>Fully Qualified Domain Name</alt></acronym>.
 </simpara>&sost-raw-too;</listitem></varlistentry>
 <varlistentry id="sost-local"><term><code>(&sost-local;
    &sost-r; [<replaceable>do-not-resolve-p</replaceable>])</code></term>
  <listitem><simpara>The dual to &sost-peer; - same information,
   host name and port number, but for the local host.
   The difference from &sost-host; and &sost-port; is that this function
   asks the OS (and thus returns the correct trusted values) while the
   other two are just accessors to the internal data structure, and
   basically return the arguments given to the function which created
   the &sost-r;.</simpara>&sost-raw-too;</listitem></varlistentry>
 <varlistentry id="sost-shut"><term><code>(&sost-shut; &sost-r;
    &direction-r;)</code></term>
  <listitem><simpara>Some protocols provide for closing the connection
   in one &direction-r; using <function role="unix">shutdown</function>.
   This function provides an interface to this &unix; system call.
   &direction-r; should be &input-k; or &output-k;.  Note that you
   should still call &close; after you are done with your &sost-r;; this
   is best accomplished by using &with-open-stream;.</simpara>
   <para>All &socket-stream;s are &bidi-s;s (i.e., both &input-stream-p;
   and &output-stream-p; return &t; for them).
   &sost-shut; <emphasis>breaks</emphasis> this and turns its argument
   stream into an &in-s; (if &direction-r; is &output-k;) or &out-s; (if
   &direction-r; is &input-k;).
    Thus, the following important invariant is preserved: whenever
   <itemizedlist><listitem><simpara>a &stream-t; is open
    (i.e., &open-stream-p; returns &t;) and</simpara></listitem>
   <listitem><simpara>a &stream-t; is an &in-s; (i.e., &input-stream-p;
     returns &t;)</simpara></listitem></itemizedlist>
   the &stream-t; can be read from (e.g., with &read-char; or &read-byte;).
   </para>&sost-raw-too;</listitem></varlistentry>
 <varlistentry id="so-opt"><term><code>(&so-opt; &sose-r; &rest-amp;
    {&option-r;}*)</code></term>
  <listitem><simpara>Query and, optionally, set socket options using
   <function role="unix">getsockopt</function> and &setsockopt;.
   An &option-r; is a keyword, optionally followed by the new value.
   When the new value is not supplied, &setsockopt; is not called.
   For each option the old (or current, if new value was not supplied)
   value is returned.  E.g., <code>(&so-opt; &sose-r;
   :SO-LINGER 1 :SO-RCVLOWAT)</code> returns 2 values: &nil;, the old
   value of the <constant>:SO-LINGER</constant> option, and 1, the
   current value of the <constant>:SO-RCVLOWAT</constant> option.
  </simpara>&sost-raw-too;</listitem></varlistentry>
 <varlistentry id="st-handles"><term><code>(&st-handles;
    &stream-r;)</code></term>
  <listitem><simpara>Return the input and output OS &file-des;s of the
    &stream-r; as &mul-val;.  See <xref linkend="rawsock"/>.
 </simpara></listitem></varlistentry>
</variablelist></section>
<!-- #endif -->
<section id="timeout-k"><title>Argument &timeout-k;</title>
<para>The &timeout-k; argument specifies the number of &seconds; to wait for
 an event. The value may be a<itemizedlist>
 <listitem><simpara>a non-negative &real-t; or</simpara></listitem>
 <listitem><simpara>a &list-t; <literal role="data">(sec usec)</literal>
  or</simpara></listitem>
 <listitem><simpara>a &cons-t; cell <literal role="data">(sec .
   usec)</literal>.</simpara></listitem>
</itemizedlist></para></section>
</section>

<section id="mt"><title>Multiple Threads of Execution</title>
<subtitle><emphasis role="plat-dep">Only in &clisp; built &with;
  configure-time flag <option>--with-threads</option>.</emphasis></subtitle>
<!-- #ifdef MULTITHREAD -->
<warning><simpara>This functionality is &experimental;.</simpara>
 <simpara>Use it at your own risk.</simpara>
 <simpara>Discuss it on <ulink url="ml">clisp-devel</ulink>.</simpara></warning>

<section id="mt-intro"><title>Introduction</title>
<para>&clisp; uses the OS threads to implement multiple threads of execution.
 Two flavors are supported: &posix; and &win32;. Both are preemptive.</para>
<para>All symbols are exported from the package &mt-pac;, which has nicknames
 <quote role="package">MT</quote> (for <emphasis>MultiThreading</emphasis>) and
 <quote role="package">MP</quote> (for <emphasis>MultiProcessing</emphasis>).
 When this functionality is present, &features-my;
 contains the symbol <constant>:MT</constant>.</para>
<para>See also <xref linkend="gc-mt"/>.</para></section>

<section id="mt-general"><title>General principles</title>

<section id="mt-parallelizability"><title>Parallelizability</title>

<para>A program developed for a single-threaded world which shares no
 application objects with programs running in other threads must run
 fine, without problems.</para>

<para>Specfically:
 if, in a single-threaded world, execution of program A before program B
 produces semantically the same results as execution of program B before
 program A, then in a multithreaded world, it is possible to run A and B
 simultaneously in different threads, and the result will be the same as
 in the two single-threaded cases (A before B, or B before A).
 <itemizedlist><title>Summary</title>
  <listitem><simpara>If A and B have no common objects, then the
    implementation ensures that the principle is fulfilled.</simpara></listitem>
  <listitem><simpara>If A and B share some objects, the implementation
    allows the programs to satisfy the principle with little effort.
</simpara></listitem></itemizedlist></para></section>

<section id="mt-symvalue"><title>Special Variable Values</title>
<para>Every &dyn-var; has a global value that can be shared across all
 &thread;s.</para>
<para>Bindings of &dyn-var;s (via &let;/&let-star;/&multiple-value-bind;)
 are local to &thread;s, i.e. every &symbol-t; has a different value cell in
 each &thread;.  &symbol-value-thread; can be used to inspect and modify
 these thread local bindings.</para>
<para>Threads do not inherit dynamic bindings from the parent thread.</para>

<para>Example:<programlisting language="lisp">
(defvar *global* 1)<lineannotation>create a &glob-var;</lineannotation>
(defun thread-1 ()
   <lineannotation>here *global* and (&symbol-value; *global*) will be 1 not 2!</lineannotation>
  (setq *global* 5)<lineannotation>change the &glob-var; value</lineannotation>
  (let ((*global* 10))<lineannotation>&thr-var; value is initialized</lineannotation>
    (setq *global* 20)<lineannotation>&thr-var; value is changed</lineannotation>
    <lineannotation>&glob-var; value is not accessible here (only via &symbol-value-thread;)</lineannotation>
    )
  (setq *global* 30))<lineannotation>&glob-var; value is modified again</lineannotation>
(let ((*global* 2))<lineannotation>&thr-var; value is initialized</lineannotation>
  (&make-thread; #'thread-1))
</programlisting></para>

</section>

<section id="mt-package"><title>Packages</title>
<note><para>Locking discussed in this section has nothing to do with
  &package-lock;.</para></note>
<para>&package-t; objects have an internal &mutex; and are locked by
 &intern; before adding a symbol (if &find-symbol; fails).  All
 modifications of internal package data are guarded by this &mutex;.</para>
<para>While iterating over package symbols with &do-symbols;,
 &do-external-symbols;, &do-all-symbols;, &with-package-iterator;
 or the &loop; <ulink role="clhs" url="sec_6-1-2-1-7">for-as-package
  subclause</ulink> the package being iterated over is also locked.</para>
</section>

<section id="mt-clos"><title>&clos;</title>
 <subtitle>This information is likely to change in the near future</subtitle>
<para>&clos; is &not-e; thread-safe. &defclass;, &defgeneric;,
 &defmethod;, &defstruct; modify &clos; without any locking and may
 interfere with each other.</para>
<para>It is recommended that all code is &load;ed &before-e;
 any &thread;s are spawned.</para></section>

<section id="mt-mutable"><title>Hash Tables, Sequences, and other
  mutable objects</title>
<subtitle>If you want to shoot yourself, it is <emphasis>your</emphasis>
 responsibility to wear armor.</subtitle>

<para>Nothing is ever locked automatically (automatic locking will
 impose an unjustifiable penalty on &hash-table-t;s and &sequence-t;s
 local to threads), so the user must use locks when sharing
 &hash-table-t;s, &sequence-t;s and user-defined mutable objects between
 threads.</para>
<para>This approach is consistent with the usual &cl; approach:
 <blockquote><attribution><ulink role="clhs" url="sec_3-6"/></attribution>
  <para>The consequences are undefined when code executed during an
   object-traversing operation destructively modifies the object in a
   way that might affect the ongoing traversal operation...
 </para></blockquote>
 <blockquote><attribution><ulink role="clhs" url="sec_18-1-2"/></attribution>
  <para>If an object O1 is used as a key in a hash table H and is then
   visibly modified with regard to the equivalence test of H, then the
   consequences are unspecified if O1 is used as a key in further
   operations on H...</para></blockquote></para>

<section id="mt-random"><title>&random; and &random-state-t;</title>
<para>&random; modifies a &random-state-t; &without; locking, which
means that you &cannot-e; carelessly share such objects between threads.
However, &random-state-var; is bound per-thread (see &make-thread; and
&default-special-bindings;), i.e., each thread has its own value and
thus &random; &is-e; thread-safe.</para></section>

</section>

<section id="mt-unsafe"><title>Examples of thread-unsafe code</title>
<para>Here are some forms whose results are undefined if two threads
 evaluate them without locking:<programlisting language="lisp">
(&incf; (&gethash; x global-ht 0))<lineannotation>see <xref linkend="mt-mutable"/></lineannotation>
(&setf; (&aref; global-array ...) ...)<lineannotation>ditto</lineannotation>
(&defmethod; &gf-r; (...) ...)<lineannotation>see <xref linkend="mt-clos"/></lineannotation>
</programlisting></para>
<warning><simpara>The above code may result in a segfault!</simpara>
<simpara>This is the reason why the multithreading support is still
&experimental;. However, if you do not share global &hash-table-t;s
between your threads and define all your &clos; methods &before-e;
spawning threads, multithreading should work fine.</simpara></warning>
</section>

</section>

<section id="mt-api"><title>Thread API reference</title>
<variablelist>
<varlistentry id="thread"><term>&thread;</term>
 <listitem><simpara>The type of the object returned by &make-thread;.</simpara>
  <simpara>Each &thread; represent a separate computation, executed in
   parallel to each other.</simpara></listitem></varlistentry>
<varlistentry id="make-thread"><term><code>(&make-thread; &func-r;
   &key-amp; &name-k; :INITIAL-BINDINGS :CSTACK-SIZE :VSTACK-SIZE)</code></term>
 <listitem><simpara>Start a new named &thread; running &func-r;.</simpara>
  <variablelist>
   <varlistentry><term><constant>:INITIAL-BINDINGS</constant></term>
    <listitem><simpara>an &alist; of <literal role="data">(&symbol-r;
       . &form-r;)</literal>.
      The &form-r;s are &eval;uated in the context of the new thread
      and &symbol-r;s are bound to the result in the thread before &func-r; is
      called. The default value is &default-special-bindings;.</simpara>
      <simpara>The main purpose of this argument is to initialize some
      global data that should not be shared between threads, e.g.,
      &random-state-var;, &readtable-var;.</simpara>
      <simpara>When using <constant>:INITIAL-BINDINGS</constant> it is
      best to &cons; the application-specific data in front of
      &default-special-bindings; or copy and modify it to fit the
      application needs.</simpara>
    <note><simpara>When the same &symbol-r; appears in this &alist; multiple
     times, the <emphasis>first</emphasis> occurrence determines the value.
   </simpara></note></listitem></varlistentry>
   <varlistentry><term><constant>:CSTACK-SIZE</constant></term>
    <listitem><simpara>the size in bytes of the control (&c-lang;) stack.
      If 0, the value is decided by the OS.</simpara></listitem></varlistentry>
  <varlistentry><term><constant>:VSTACK-SIZE</constant></term>
   <listitem><simpara>the size of the &clisp; &STACK; in &object-t;s.
     The default value is calculated based on the &opt-m; option
     used when &clisp; was started.
     If 0, the value will be the same as that of the calling thread.
  </simpara></listitem></varlistentry></variablelist>
  <simpara>If &thread; creation fails (e.g., due to a lack of system
   memory), a &control-error-t; is &signal;ed.</simpara>
  <simpara>Cf. <function role="unix">pthread_create</function>.</simpara>
</listitem></varlistentry>
<varlistentry id="threadp"><term><code>(&threadp; &object-r;)</code></term>
 <listitem><simpara>Check whether the object is of type &thread;.
</simpara></listitem></varlistentry>
<varlistentry id="thread-yield"><term><code>(&thread-yield; &thr;)</code></term>
 <listitem><simpara>Relinquish the CPU.  The &thr; is placed at the end
   of the run queue and another thread is scheduled to run.</simpara>
  <simpara>Cf. <function role="unix">sched_yield</function>.</simpara>
</listitem></varlistentry>
<varlistentry id="thread-interrupt"><term><code>(&thread-interrupt; &thr;
   &key-amp; &function-k; &override-k; &arguments-k;)</code></term>
 <listitem><simpara>Interrupt the normal execution flow in &thr; and ask
   it to &apply; &func-r; to &args-r;.</simpara>
  <simpara>Use <code>(&thread-interrupt; &thr; &function-k; &nil;)</code>
   to debug &thr; and <code>(&thread-interrupt; &thr; &function-k;
    &t;)</code> to terminate &thr;.</simpara>
  <simpara>The &override-k; argument overrides &with-deferred-interrupts;
   and should be used with extreme care.</simpara>
  <simpara>Threads can only be interrupted at a point where the &gc;ion
   can run, see <xref linkend="gc-mt"/>.</simpara>
  <simpara>Currently on &win32; blocking I/O cannot be interrupted.
   The interrupt will be handled after the call returns.</simpara>
  <warning><para>Thread may be interrupted inside &unwind-protect;'s
    cleanup forms and on non-local exit from &func-r; -
    they may not execute entirely.  In order to prevent this,
    &with-deferred-interrupts; is provided.</para></warning>
</listitem></varlistentry>
<varlistentry id="thread-name"><term><code>(&thread-name; &thr;)</code></term>
 <listitem><simpara>Return the &name-r; of the &thr;.
</simpara></listitem></varlistentry>
<varlistentry id="thread-active-p"><term><code>(&thread-active-p;
   &thr;)</code></term>
 <listitem><simpara>Return &nil; if the thread has already terminated
   and &t; otherwise.</simpara>
  <warning><para>By the time this function returns &t;, &thr; may have
    already terminated anyway.</para></warning></listitem></varlistentry>
<varlistentry id="current-thread"><term><code>(&current-thread;)</code></term>
 <listitem><simpara>Return the &thread; object encapsulating the caller.
</simpara></listitem></varlistentry>
<varlistentry id="list-threads"><term><code>(&list-threads;)</code></term>
 <listitem><simpara>Return the &list-t; of all currently running &thread;s.
  </simpara><warning><para>By the time this function returns, the set of
    actually running threads may have a single intersection with the
    return value - the &current-thread;.
</para></warning></listitem></varlistentry>
<varlistentry id="mutex"><term>&mutex;</term>
 <listitem><simpara>The type of the object return by &make-mutex;.</simpara>
  <simpara>This represents a <emphasis>lock</emphasis>, i.e., a way to
   prevent different threads from doing something at the same time,
   e.g., modifying the same object.</simpara></listitem></varlistentry>
<varlistentry id="mutexp"><term><code>(&mutexp; &object-r;)</code></term>
 <listitem><simpara>Check whether the object is of type &mutex;.
</simpara></listitem></varlistentry>
<varlistentry id="make-mutex"><term><code>(&make-mutex; &key-amp;
   &name-k; <constant>:RECURSIVE-P</constant>)</code></term>
 <listitem><simpara>Create new &mutex; object - not locked by any thread.
   &name-k; should be a &string-t; describing the mutex (this really helps
   debugging deadlocks).  When <replaceable>RECURSIVE-P</replaceable> is
   non-&nil;, a recursive &mutex; is created i.e., a thread can acquire
   the mutex repeatedly (and should, of course, release it for each
   successful acquisition).</simpara>
  <simpara>Cf. <function role="unix">pthread_mutex_init</function>.</simpara>
</listitem></varlistentry>
<varlistentry id="mutex-name"><term><code>(&mutex-name; &thr;)</code></term>
 <listitem><simpara>Return the &name-r; of the &mutex;.
</simpara></listitem></varlistentry>
<varlistentry id="mutex-lock"><term><code>(&mutex-lock; &mutex-r;
   &key-amp; &timeout-k;)</code></term>
 <listitem><simpara>Acquire the &mutex-r;.  If &mutex-r; is locked by
   another thread, the call blocks and waits up to &timeout-k; &seconds;.
   If &timeout-k; is not specified, waits forever.</simpara>
  <simpara>Return &t; on a successful locking of &mutex-r;, and &nil; on
   timeout.</simpara>
  <para>If the calling thread has already acquired &mutex-r;, then
   <itemizedlist><listitem><simpara>if &mutex-r; is recursive, &t; is
      returned (for each recursive &mutex-lock; there should be a
      separate &mutex-unlock;);</simpara></listitem>
    <listitem><simpara>If &mutex-r; is non-recursive an &err-sig; to
      avoid a deadlock.</simpara></listitem></itemizedlist></para>
  <simpara>Cf. <function role="unix">pthread_mutex_lock</function>.</simpara>
</listitem></varlistentry>
<varlistentry id="mutex-unlock"><term><code>(&mutex-unlock;
   &mutex-r;)</code></term>
 <listitem><simpara>Release (unlock) &mutex-r;. If the calling thread is
   not locking &mutex-r;, an &err-sig;.</simpara>
  <simpara>Cf. <function role="unix">pthread_mutex_unlock</function>.</simpara>
</listitem></varlistentry>
<varlistentry id="mutex-owner"><term><code>(&mutex-owner;
   &mutex-r;)</code></term>
 <listitem><simpara>Return the &thread; that owns (locks) &mutex-r;,
   or &nil; if &mutex-r; is not locked.</simpara>
  <warning><para>By the time this function returns the &mutex-r;
    ownership may have changed (unless the owner is the
    &current-thread;). The function is mostly useful for debugging
    deadlocks.</para></warning></listitem></varlistentry>
<varlistentry id="mutex-recursive-p"><term><code>(&mutex-recursive-p;
   &mutex-r;)</code></term>
 <listitem><simpara>Return a indicator whether &mutex-r; is recursive.
</simpara></listitem></varlistentry>
<varlistentry id="with-mutex-lock"><term><code>(&with-mutex-lock; (&mutex-r;)
   &body-amp; &body-r;)</code></term>
 <listitem><simpara>Execute &body-r; with &mutex-r; locked.
   Upon exit &mutex-r; is released. Return whatever &body-r; returns.
</simpara></listitem></varlistentry>
<varlistentry id="exemption"><term>&exemption;</term>
 <listitem><simpara>The type of the object returned by &make-exemption;.
   These correspond to the &posix; condition variables,
   see <filename role="unix">pthread.h</filename>.</simpara>
  <simpara>These objects allow broadcasting state from one &thread; to
   the others.</simpara></listitem></varlistentry>
<varlistentry id="exemptionp"><term><code>(&exemptionp;
   &object-r;)</code></term>
  <listitem><simpara>Check whether the object is of type &exemption;.
</simpara></listitem></varlistentry>
<varlistentry id="make-exemption"><term><code>(&make-exemption;
   &key-amp; &name-k;)</code></term>
 <listitem><simpara>Create a new &exemption; object.
   &name-k; should be a &string-t; describing the exemption (this really
   helps debugging deadlocks).</simpara>
  <simpara>Cf. <function role="unix">pthread_cond_init</function>.</simpara>
</listitem></varlistentry>
<varlistentry id="exemption-name"><term><code>(&exemption-name;
   &exemp-r;)</code></term>
 <listitem><simpara>Return the &name-r; of the &exemp-r;.
</simpara></listitem></varlistentry>
<varlistentry id="exemption-signal"><term><code>(&exemption-signal;
   &exemp-r;)</code></term>
 <listitem><simpara>Signal &exemp-r; object, i.e. wake up a thread blocked
   on waiting for &exemp-r;.</simpara>
  <simpara>Cf. <function role="unix">pthread_cond_signal</function>.</simpara>
</listitem></varlistentry>
<varlistentry id="exemption-wait"><term><code>(&exemption-wait;
   &exemp-r; &mutex-r; &key-amp; &timeout-k; &test-k;)</code></term>
 <listitem><simpara>Wait for another &thread; to call &exemption-signal;
   or &exemption-broadcast; on &exemp-r;.
   &mutex-r; should be locked by the caller; otherwise an &err-sig;.
   The function releases the &mutex-r; and waits for &exemp-r;.
   On return &mutex-r; is acquired again.</simpara>
  <simpara>When using exemptions there is always a boolean &pred-r; involving
   shared variables associated with each exemption wait that is true if the
   thread should proceed.</simpara>
  <simpara>The function waits up to &timeout-k; &seconds;.
   If timeout is not specified, waits forever.</simpara><simpara>
   Returns &t; if &exemp-r; was signaled and &nil; on timeout.</simpara>
  <para>On &posix; it is possible to have
   <ulink url="http://en.wikipedia.org/wiki/Spurious_wakeup">spurious
    wakeup</ulink>s, i.e., this function may return &t; even though no
   thread called &exemption-broadcast; or &exemption-signal;.
   Therefore, a common idiom for using this function is: <code>(&loop;
   :until (&pred-r;) :do (&exemption-wait; &exemp-r; &mutex-r;))</code></para>
  <simpara>The &test-k; argument simplifies this. When supplied,
   &exemption-wait; returns when either &test-k; &pred-r; is satisfied
   (always called while &mutex-r; is held) or when &timeout-k; elapses.
   The above loop is equivalent to: <code>(&exemption-wait; &exemp-r;
    &mutex-r; &test-k; #'&pred-r;)</code>.
   When &test-k; is supplied, &exemption-wait; returns &t; when &exemp-r; was
   signaled and &test-k; &pred-r; is satisfied and &nil; on timeout.
   </simpara><simpara>This is the preferred and most portable way to wait on
     an exemption.</simpara>
  <simpara>Cf. <function role="unix">pthread_cond_wait</function>.</simpara>
</listitem></varlistentry>
<varlistentry id="exemption-broadcast"><term><code>(&exemption-broadcast;
   &exemp-r;)</code></term>
 <listitem><simpara>Signal &exemp-r; to all threads waiting for it.</simpara>
  <simpara>Cf. <function role="unix">pthread_cond_broadcast</function>.
</simpara></listitem></varlistentry>
<varlistentry id="y-or-n-p-timeout"><term><code>(&y-or-n-p-timeout;
   seconds default &rest-amp; &args-r;)</code></term>
 <term><code>(&yes-or-no-p-timeout; seconds default &rest-amp;
   &args-r;)</code></term>
 <listitem><simpara>Similar to &y-or-n-p; and &yes-or-no-p;, but use
   &with-timeout; to return <replaceable>DEFAULT</replaceable> when no
   reply is given within timeout &seconds;.</simpara></listitem></varlistentry>
<varlistentry id="with-timeout"><term><code>(&with-timeout;
   (seconds &body-amp; timeout-forms) &body-amp; &body-r;)</code></term>
 <listitem><simpara>Execute &body-r;. If it does not finish for up to
   &seconds;, it is interrupted and <replaceable>timeout-forms</replaceable>
   are executed.</simpara>
  <simpara>Return the values of the last evaluated form in either
   &body-r; or <replaceable>timeout-forms</replaceable>.</simpara>
  <warning><para>Since on timeout the current thread is interrupted,
    special care may be needed for ensuring proper cleanup in &body-r;.
    See &thread-interrupt; and &with-deferred-interrupts;.</para></warning>
</listitem></varlistentry>
<varlistentry id="symbol-value-thread"><term><code>(&setf;
   (&symbol-value-thread; &symbol-r; &thr;) &value-r;)</code></term>
 <term><code>(&symbol-value-thread; &symbol-r; &thr;)</code></term>
 <listitem><simpara>Access or set the &thr-var; value.
   When &thr; is &t;, use the &current-thread;; if it is &nil;, use the
   &glob-var; binding.
   Returns two values: the &symbol-r; binding and an indicator: &nil; if
   not bound in the &thr;, &t; if bound, and &symbol-t; &makunbound; if
   the &thr-var; binding was removed with &makunbound;.
</simpara></listitem></varlistentry>
<varlistentry id="default-special-bindings">
 <term>&default-special-bindings;</term>
 <listitem><simpara>The default <constant>:INITIAL-BINDINGS</constant>
   argument of &make-thread;.</simpara></listitem></varlistentry>
<varlistentry id="with-deferred-interrupts"><term>
  <code>(&with-deferred-interrupts; &body-amp; &body-r;)</code></term>
 <listitem><simpara>Defer thread interrupts (but &not-e; thread
   preemption) while &body-r; is executed.  If there is an interrupt
   while &body-r; is run, it is queued and will be executed after
   &body-r; finishes.</simpara>
  <warning><para>Care is needed if waiting or blocking in &body-r;,
    since there is no way to interrupt it (in case of a deadlock).
    The macro was added to avoid partial &unwind-protect;'s cleanup
    forms evaluation in case they are interrupted with a non-local exit.
</para></warning></listitem></varlistentry>
<varlistentry id="thread-join"><term><code>(&thread-join; &thr; &key-amp;
   &timeout-k;)</code></term>
 <listitem><simpara>Wait for &thr; to terminate and return two values:
  &thr;'s &mul-val; as a &list-t; and a &boolean-t; indicator of whether &thr;
  finished normally or has been interrupted with &thread-interrupt;.</simpara>
 <simpara>This function uses &exemption-wait; (and &not-e;
  <function role="unix">pthread_join</function>), so there are no resource
  leaks normally associated with this function.</simpara>
 <simpara>On timeout, return &mul-val; &nil; and &timeout-k;.</simpara>
 <simpara>This function can be used repeatedly on the same thread,
  so this is the usual way to access the return values of a finished
  thread.</simpara></listitem></varlistentry>
</variablelist></section>
<!-- #endif -->
</section>

<section id="quickstart"><title>Quickstarting delivery with &clisp;</title>

<para>This section describes three ways to turn &clisp; programs into
 executable programs, which can be started as quickly as executables
 written in other languages.</para>

<section id="quickstart-summary"><title>Summary</title>
<variablelist>
 <varlistentry><term>&unix;</term>
  <listitem><simpara>&clisp; can act as a script interpreter.
  </simpara></listitem></varlistentry>
 <varlistentry><term>Desktop environments such as &kde;, &gnome;,
   &macosx; or &win32;.</term>
  <listitem><simpara>Files created with &clisp; can be associated with
   the &clisp; executable so that clicking on them would make &clisp;
   execute the appropriate code.</simpara></listitem></varlistentry>
 <varlistentry><term>&linux; kernel with
   <option>CONFIG_BINFMT_MISC=y</option></term>
  <listitem><simpara>Associate the extensions &fasl-file;
    and &lisp-file; with &clisp;; then you can make the
    files executable and run them from the command line.
 </simpara></listitem></varlistentry>
</variablelist>

<note id="quickstart-multifile"><title>Multi-file applications</title>
 <para>These three techniques apply to a single &lisp-file; or
  &fasl-file; file.  If your application is made up of several
  &lisp-file; or &fasl-file; files, you can simply concatenate them
  (using <command role="unix">cat</command>) into one file; the
  techniques then apply to that concatenated file.</para></note>

<note id="quickstart-lispless"><title>Lisp-less target</title>
 <para>These three techniques assume that the target machine has &clisp;
  pre-installed and thus you can deliver just your own application, not
  &clisp; itself.  If you want to deliver applications without assuming
  anything about your target box, you have to resort to creating
  executable &mem-image;s.</para></note>
</section>

<!-- #ifdef UNIX -->
<section id="quickstart-unix"><title>Scripting with &clisp;</title>
 <subtitle>&unix-only;</subtitle>

<para>On &unix;, a text file (&fasl-file; or &lisp-file;) can
 be made executable by adding a first line of the form
 <screen>#!&interp-r; [&interp-args;]</screen>
 and using <command role="unix">chmod</command> to make the file
 executable.</para>

<formalpara><title>OS Requirements</title>
 <para>&clisp; can be used as a script interpreter under the following
 conditions:
<itemizedlist>
<listitem><simpara>The &interp-r; must be the full pathname of &clisp;.
 The recommended path is <filename>/usr/local/bin/clisp</filename>,
 and if &clisp; is actually installed elsewhere, making
 <filename>/usr/local/bin/clisp</filename> be a symbolic link to the
 real &clisp;.</simpara></listitem>
<listitem><simpara>The &interp-r; must be a real executable, not a script.
 Unfortunately, in the binary distributions of &clisp; on Solaris,
 &clisp-cmd; is a shell script because a &c-lang; compiler cannot be
 assumed to be installed on this platform.  If you do have a &c-lang;
 compiler installed, build &clisp; from the source yourself;
 <command role="unix">make install</command> will install &clisp-cmd; as
 a real executable.</simpara></listitem>
<listitem><para>On some platforms, the first line which specifies the
 interpreter is limited in length:
   <itemizedlist>
     <listitem><simpara>max. 32 characters on SunOS 4,</simpara></listitem>
     <listitem><simpara>max. 80 characters on HP-UX,</simpara></listitem>
     <listitem><simpara>max. 127 characters on &linux;.</simpara></listitem>
   </itemizedlist>
   Characters exceeding this limit are simply cut off by the system.
   At least 128 characters are accepted on Solaris, IRIX, AIX, OSF/1.
   There is no workaround: You have to keep the interpreter pathname
   and arguments short.</para></listitem>
<listitem><simpara>On Solaris and HP-UX, only the first
 <replaceable>interpreter-arg</replaceable> is passed to the &interp-r;.
 In order to pass more than one option (for example, &opt-M; and
 &opt-C;) to &clisp;, separate them with
 <ulink url="http://www.fileformat.info/info/unicode/char/00a0/">no-break
 spaces</ulink> instead of normal spaces.  (But the separator between
 &interp-r; and &interp-args; must still be a normal space!) &clisp;
 will split the &interp-args; both at no-break spaces and at normal spaces.
</simpara></listitem></itemizedlist></para></formalpara>

<formalpara id="script-exec"><title>Script execution</title>
<para><itemizedlist><listitem><simpara>The &script; should contain Lisp
   forms, except in the <literal>#!</literal> line.</simpara></listitem>
  <listitem><simpara>The file is loaded normally, through the function
   &load-my; (in particular, the name of the script file, which
   is <envar>$0</envar> in &sh;, can be found in &load-truename-var; and
   &load-pathname-var;).</simpara></listitem>
  <listitem><simpara>Before it is loaded, the variable &args; is bound
   to a &list-t; of &string-t;s, representing the arguments given to the
   Lisp script (i.e., <envar>$1</envar> in &sh; becomes <code>(&first;
     &args;)</code> etc).</simpara></listitem>
  <listitem><simpara>The standard &unix; i/o facilities (see &stdio;)
    are used: &standard-input-var; is bound to &stdin;,
    &standard-output-var; to &stdout;, and &error-output-var; to &stderr;.
    Note <xref linkend="dribble-script"/>.</simpara></listitem>
  <listitem><simpara>The &cont-err;s will be turned into &warning-t;s
   (using &appease-cerrors;).</simpara></listitem>
  <listitem><simpara>Non-&cont-err;s and &ctrl-c; interrupts will
   terminate the execution of the Lisp script with an error status
   (using &exit-on-error;).</simpara></listitem>
  <listitem><simpara>If you wish the script's contents to be compiled
    during loading, add &opt-C; to the &interp-args;.
</simpara></listitem></itemizedlist></para></formalpara>

<formalpara id="script-bad"><title>If nothing works</title>
<para>Another, quite inferior, alternative is to put the following into a file:
<programlisting language="shell">
#!&sh;
exec &clisp-cmd; &lt;&lt;EOF
(lisp-form)
(another-lisp-form)
(yet-another-lisp-form)
EOF
</programlisting>
The problem with this approach is that the return values of each form
will be printed to &standard-output-var;.
Another problem is that no user input will be available.</para></formalpara>
</section>
<!-- #endif -->

<section id="quickstart-desktop"><title>Desktop Environments</title>
 <subtitle><emphasis role="plat-dep">&win32;, &gnome;, &kde;, &macosx;
  desktop platforms only.</emphasis></subtitle>

<note id="quickstart-desktop-win32"><title>Notations</title>
<para>Although we use &win32;-specific notation, these techniques work
 on other desktop environments as well.</para></note>

<para>There are two different ways to make &clisp;
 <quote>executables</quote> on desktop platforms.</para>

<orderedlist>
 <listitem><simpara>Associate the &mem-file; extension with
   <command>c:\clisp\clisp.exe &opt-M; "%s"</command>.
  </simpara></listitem>
 <listitem><simpara>Associate the &fasl-file; extension with
   <command>c:\clisp\clisp.exe &opt-i; "%s"</command>
    Alternatively, you may want to have a function
    <function>main</function> in your &fasl-file; files and associate
    the &fasl-file; extension with <command>c:\clisp\clisp.exe &opt-i;
     %s &opt-x; (main)</command>.
  </simpara></listitem>
</orderedlist>

<para>Then clicking on the compiled lisp file (with &fasl-file;
 extension) will load the file (thus executing all the code in the
 file), while the clicking on a &clisp; &mem-image; (with &mem-file;
 extension) will start &clisp; with the given &mem-image;.</para>

<note><para>On &win32;, &clisp; is distributed with a file
 <filename role="clisp-cvs">src/install.bat</filename>, which
 runs <filename role="clisp-cvs">src/install.lisp</filename> to create a
 file <filename>clisp.lnk</filename> on your desktop and also associates
 &fasl-file;, &lisp-file;, and &mem-file; files with &clisp;.</para></note>

</section>

<section id="quickstart-linux">
 <title>Associating extensions with &clisp; via kernel</title>
 <subtitle><emphasis role="plat-dep">&linux; platforms only.
 </emphasis></subtitle>

<para>You have to build your kernel with
 <option>CONFIG_BINFMT_MISC=y</option> and
 <option>CONFIG_PROC_FS=y</option>.  Then you will have a
 <filename>/proc/sys/fs/binfmt_misc/</filename> directory and you will
 be able to do (as <literal role="login">root</literal>; you might want to put
 these lines into <filename>/etc/rc.d/rc.local</filename>):

<screen><prompt>#</prompt> echo ":CLISP:E::fas::/usr/local/bin/clisp:" &gt;&gt; /proc/sys/fs/binfmt_misc/register
<prompt>#</prompt> echo ":CLISP:E::lisp::/usr/local/bin/clisp:" &gt;&gt; /proc/sys/fs/binfmt_misc/register</screen></para>

<para>Then you can do the following:
<screen>&sh-prompt; cat &lt;&lt; EOF &gt; hello.lisp
(print "hello, world!")
EOF
&sh-prompt; &clisp-cmd; &opt-c; hello.lisp
;; Compiling file hello.lisp ...
;; Wrote file hello.fas
0 errors, 0 warnings
&sh-prompt; chmod +x hello.fas
&sh-prompt; hello.fas

"hello, world!"</screen></para>

<para>Please read
 <ulink url="http://www.kernel.org/doc/Documentation/binfmt_misc.txt">
  <filename>/usr/src/linux/Documentation/binfmt_misc.txt</filename></ulink>
 for details.</para>
</section>

</section>

<section id="shell"><title>Shell, Pipes and Printing</title>

<para>This section describes how &clisp; can invoke external
 executables and communicate with the resulting processes.</para>

<section id="exec"><title>Shell</title>

<variablelist>
<!-- #ifdef UNIX -->
<varlistentry><term>&unix-only;</term>
 <listitem><simpara><code>(&exec; &program-r;
       <replaceable>arg&sub-1;</replaceable>
       <replaceable>arg&sub-2;</replaceable> ...)</code>
   executes an external program.
   Its name is &program-r; (a full pathname).
   It is given the &string-t;s <replaceable>arg&sub-1;</replaceable>,
   <replaceable>arg&sub-2;</replaceable>, ... as arguments.
 </simpara></listitem></varlistentry>
<!-- #endif -->

<varlistentry><term>&unix-w32-only;</term>
 <listitem><simpara><code>(&shell; [&command-r;])</code>
   calls the operating system's shell.</simpara>
  <simpara><code>(&shell;)</code> calls the shell for interactive use.</simpara>
  <para><code>(&shell; &command-r;)</code> calls the shell
   only for execution of the one given &command-r;, which can be a
   complex expression: <programlisting language="lisp">
(&shell; "for x in 1 2 3; do echo $x; done")
1
2
3
<computeroutput>&nil;</computeroutput></programlisting></para>
<variablelist><varlistentry><term>&unix-only;</term>
 <listitem><simpara>&exec; is called on the value of the &env-var;
  <envar>SHELL</envar> if used interactively;
  <command>&sh; -c &command-r;</command> if used non-interactively.
</simpara></listitem></varlistentry>
<varlistentry><term>&win32-only;</term>
 <listitem><simpara><function role="win32">CreateProcess</function> is
 called on <code>(&or-m; &command-r; (&getenv; <envar>COMSPEC</envar>))</code>
</simpara></listitem></varlistentry></variablelist>
</listitem></varlistentry>

<!-- #ifdef PIPES2 -->
<varlistentry id="run-prog"><term>&unix-w32-only;</term>
 <listitem><simpara>The functions &run-cmd; and &run-prog; are the
   general interface to &shell; and the above:</simpara>

  <simpara><code>(&run-cmd; &command-r; &key-amp;
    <constant>:MAY-EXEC</constant> <constant>:INDIRECTP</constant>
    &input-k; &output-k; &if-output-exists; &wait-k;)</code>
   runs a shell command (including shell built-in commands,
   like <command>DIR</command> on &win32;
   and <command>for/do/done</command> on &unix;).</simpara>

  <simpara><code>(&run-prog; &program-r; &key-amp;
    <constant>:MAY-EXEC</constant> <constant>:INDIRECTP</constant>
    &arguments-k; &input-k; &output-k; &if-output-exists; &wait-k;)</code>
   runs an external program.</simpara>

  <variablelist>
   <varlistentry><term>&command-r;</term>
    <listitem><simpara>the shell command.</simpara></listitem></varlistentry>
   <varlistentry><term>&program-r;</term>
    <listitem><simpara>the program.  The directories listed in the
     &env-var; <envar>PATH</envar> will be searched for it.
    </simpara></listitem></varlistentry>
   <varlistentry><term>&arguments-k;</term>
    <listitem><simpara>a list of arguments (&string-t;s) that are given
      to the program.</simpara></listitem></varlistentry>
   <varlistentry><term>&input-k;</term>
    <listitem><simpara>where the program's input is to come from: either
     <constant>:TERMINAL</constant> (&stdin;, the default) or
     &stream-k; (a Lisp &stream-t; to be created) or
     a &path-des; (an input file) or &nil; (no input at all).
   </simpara></listitem></varlistentry>
   <varlistentry><term>&output-k;</term>
    <listitem><simpara>where the program's output is to be sent to: either
     <constant>:TERMINAL</constant> (&stdout;, the default) or
     &stream-k; (a Lisp &stream-t; to be created) or
     a &path-des; (an output file) or &nil; (ignore the output).
   </simpara></listitem></varlistentry>
   <varlistentry><term>&if-output-exists;</term>
    <listitem><simpara>what to do if the &output-k; file already exists.
     The possible values are &overwrite-k;, &append-k;, &error-k;,
     with the same meaning as for &open;. The default is &overwrite-k;.
    </simpara></listitem></varlistentry>
   <varlistentry><term>&wait-k;</term>
    <listitem><simpara>whether to wait for program termination or not
     (this is useful when no i/o to the process is needed);
     the default is &t;, i.e., synchronous execution.
    </simpara></listitem></varlistentry>
<!-- #ifdef UNIX -->
   <varlistentry><term><constant>:MAY-EXEC</constant></term>
    <listitem><simpara>pass <command>exec</command> to the underlying
    shell (&unix; only).</simpara></listitem></varlistentry>
<!-- #endif -->
<!-- #ifdef WIN32 -->
   <varlistentry><term><constant>:INDIRECTP</constant></term>
    <listitem><simpara>use a shell to run the command, e.g.,
    <code>(&run-prog; "dir" :indirectp &t;)</code>
    will run the shell built-in command <command>DIR</command>.
    This argument defaults to &t; for &run-cmd; and to &nil; for &run-prog;.
    (&win32; only).</simpara></listitem></varlistentry>
<!-- #endif -->
  </variablelist>

<para>If &stream-k; was specified for &input-k; or &output-k;, a Lisp
 &stream-t; is returned.
 If &stream-k; was specified for both &input-k; and &output-k;, three
 Lisp &stream-t;s are returned, as for the function &mk-pipe-io;.
 Otherwise, the return value depends on the process termination status:
 if it exited on a signal or a core-dump,
 the signal number is returned as a negative &integer-t;,
 else, if it ended normally with 0 exit status, &nil; is returned;
 otherwise, the status is returned as a positive &integer-t;.</para>
<para>This use of &run-prog; can cause
 <link linkend="deadlock">deadlocks</link>, see &mk-pipe-io;.</para>
</listitem></varlistentry>
<!-- #endif -->
 </variablelist>
</section>

<section id="pipe"><title>Pipes</title>

<!-- #ifdef PIPES -->
<variablelist>
<varlistentry><term>&unix-w32-only;</term>
<listitem><variablelist>
<varlistentry><term><code>(&mk-pipe-in; &command-r; &key-amp; &eltype;
    &extfmt; &buffered;)</code></term>
 <listitem><simpara>returns an &in-s; that will supply the output
   from the execution of the given operating system command.
</simpara></listitem></varlistentry>

<varlistentry><term><code>(&mk-pipe-out; &command-r; &key-amp; &eltype;
   &extfmt; &buffered;)</code></term>
 <listitem><simpara>returns an &out-s; that will pass its output as
   input to the execution of the given operating system command.
</simpara></listitem></varlistentry>

<!-- #ifdef PIPES2 -->
<varlistentry><term><code>(&mk-pipe-io; &command-r; &key-amp; &eltype;
   &extfmt; &buffered;)</code></term>
<listitem><simpara>returns three values.
  The &pri-val; is a &bidi-s; that will simultaneously pass its output
  as input to the execution of the given operating system command and
  supply the output from this command as input.
  The second and third value are the &in-s; and the &out-s; that
  make up the &bidi-s;, respectively.</simpara>
 <warning><simpara>These three streams must be closed individually, see
   &iss052;.</simpara></warning>
 <warning id="deadlock"><simpara>Improper use of this function
   can lead to <emphasis>deadlocks</emphasis>.
   Use it at your own risk!</simpara>
  <simpara>A deadlock occurs if the command and your Lisp program either
   both try to read from each other at the same time or both try to
   write to each other at the same time.</simpara>
  <simpara>To avoid deadlocks, it is recommended that you fix a
   protocol between the command and your program and avoid any hidden
   buffering: use &read-char;, &read-char-no-hang;, &listen;,
   &so-status; instead of &read-line; and &read; on the input side, and
   complete every output operation by a &finish-output;.
   The same precautions must apply to the called command as well.
</simpara></warning></listitem></varlistentry>
<!-- #endif -->
</variablelist></listitem></varlistentry>
</variablelist>
<!-- #endif -->
</section>

<section id="hardcopy"><title>Printing</title>

<para>The macro
 <firstterm>&with-print;<indexterm id="with-print" significance="preferred">
   <primary><function>WITH-OUTPUT-TO-PRINTER</function>
 </primary></indexterm></firstterm>:
<programlisting language="lisp">
(&with-print; (&var-r; [&extfmt;])
  {&declaration-r;}*
  {&form-r;}*)
</programlisting>
 binds the variable &var-r; to an &out-s;
 that sends its output to the printer.</para>
</section>
</section>

<section id="getenv"><title>Operating System Environment</title>

<para>Most modern operating systems support &env-var;s that associate
 strings (<quote>variables</quote>) with other strings
 (<quote>values</quote>).  These variables are somewhat similar to the
 &special-dec; variables in &cl;: their values are inherited by the
 processes from their parent process.</para>

<para>You can access your OS &env-var;s using the function
<code>(&getenv; &optional-amp; &string-r;)</code>,
where &string-r; is the name of the &env-var;.
When &string-r; is omitted or &nil;, all the &env-var;s and their values
are returned in an &alist;.</para>

<para>You can change the value of existing &env-var;s or create new ones
 using <code>(&setf; (&getenv; &string-r;) &nval-r;)</code>.</para>

<para>Use <code>(&setf; (&getenv; &string-r;) &nil;)</code> to remove an
 &env-var; &string-r;.</para>
</section>

</chapter>
