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

<part id="extensions"><title>Extensions</title>

<chapter id="p-indep">
 <title>Extensions-1: Platform independent Extensions</title>

<section id="image"><title>Extensions-1.1. Saving an Image</title>

<para>The function
  <literal role="sexp">(<function>EXT:SAVEINITMEM</function>
    &optional-amp; (&filename-r; "lispinit.mem")
    &key-amp; :QUIET :INIT-FUNCTION :LOCKED-PACKAGES :START-PACKAGE)</literal>
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).
<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.
   </simpara></listitem></varlistentry>
 <varlistentry><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;; thus, if you want to avoid the &repl;, you have to call
   <link linkend="quit"><function>EXT:EXIT</function></link> at the end
   of the init function yourself.</simpara>
   <simpara>See <olink targetdoc="man" targetptr="opt-exec-file">the
     manual</olink> for passing command line arguments to this function.
 </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>
</variablelist>
You can use this memory image with the
<olink targetdoc="man" targetptr="opt-memfile"><option>-M</option></olink>
option.  On &unix; systems, you may compress it with &gnu; &gzip;
to save disk space.</para>

</section>

<section id="quit"><title>Extensions-1.2. Quitting &clisp;</title>

<para>The functions <literal role="sexp">(<function>EXT:EXIT</function>
 [<replaceable>errorp</replaceable>])</literal>, <literal
 role="sexp">(<function>EXT:QUIT</function>
 [<replaceable>errorp</replaceable>])</literal> and <literal
 role="sexp">(<function>EXT:BYE</function>
 [<replaceable>errorp</replaceable>])</literal> - all synonymous -
 terminate &clisp;.  If <replaceable>errorp</replaceable> is non-&nil;,
 &clisp; aborts with the supplied numeric error status, i.e.,
 the OS environment is informed that the &clisp; session did not
 succeed.</para>

</section>

<section id="i18n"><title>Extensions-1.3. Internationalization</title>

<para>"Internationalization" means to prepare a program so that it can
use multiple national languages and national cultural conventions
without requiring further source code changes.  Localization means
providing the data - mostly textual translations - necessary for an
internationalized program to work in a particular language and with
particular cultural conventions.</para>

<para>&clisp; is internationalized, and is localized for the languages
English, German, French, Spanish, Dutch and Russian.
&clisp; also supports internationalized Lisp programs, through
&ggettext;.</para>

<section id="ggettext"><title>The &ggettext;</title>

<para>&ggettext; is a set of functions, included in &clisp; or the
&c-lang; library, which permit looking up translations of strings
through message catalogs. It is also a set of tools which makes the
translation maintenance easy for the translator and the program
maintainer.</para>

<para>The &ggettext; functions are available in &clisp; in the
&i18n-pac; package, which is &re-export;ed from the &ext-pac;
package.</para>

<variablelist>
 <varlistentry id="gettext"><term><literal role="sexp">(&gettext;
  &msgid; &optional-amp; &domain; &category;)</literal></term>
  <listitem><simpara>returns the translation of the message &msgid;,
  in the given &domain;, depending on the given &category;.
  &msgid; should be an &ascii; string, and is normally the English message.
  </simpara></listitem></varlistentry>
 <varlistentry id="ngettext"><term><literal role="sexp">(&ngettext;
  &msgid; <replaceable>msgid_plural</replaceable>
  &n-r; &optional-amp; &domain; &category;)</literal></term>
  <listitem><simpara>returns the plural form of the translation for of
   &msgid; and &n-r; in the given &domain;, depending on the given
   &category;.  &msgid; and <replaceable>msgid_plural</replaceable>
   should be &ascii; strings, and are normally the English singular and
   English plural variant of the message, respectively.
   </simpara></listitem></varlistentry>
</variablelist>

<section id="domain"><title>Domain</title>
 <para>The &domain; is a string identifier denoting the program that
is requesting the translation.  The pathname of the message catalog
depends on the &domain;: usually it is located at
<filename>TEXTDOMAINDIR/l/LC_MESSAGES/domain.mo</filename>, where
&l-r; is the ISO 639 code of the language.
The notion of &domain; allows several Lisp programs running in the same
image to request translations independently of each other.</para>

<formalpara id="textdomain"><title>Function &textdomain;</title>
<para><literal role="sexp">(&textdomain;)</literal> is a
&place; that returns the default &domain;, used when no &domain;
argument is passed to the &gettext; and &ngettext; functions.
It is &setf;able.
<literal role="sexp">(&setf; &textdomain;)</literal> is usually used
during the startup phase of a program.
Note that the default &domain; is not saved in a &mem-image;.
The use of <literal role="sexp">(&setf; &textdomain;)</literal> is
recommended only for programs that are so simple that they will never
need more than one &domain;.</para></formalpara>

<formalpara id="textdomaindir"><title>Function &textdomaindir;</title>
<para><literal role="sexp">(&textdomaindir; &domain;)</literal>
is a &place; that returns the base directory, called
<filename>TEXTDOMAINDIR</filename> above, where the message
catalogs for the given &domain; are assumed to be installed.
It is &setf;able.
<literal role="sexp">(&setf; &textdomaindir;)</literal> is usually used
during the startup phase of a program, and should be used because only
the program knows where its message catalogs are installed.
Note that the <filename>TEXTDOMAINDIR</filename>s
are not saved in a &mem-image;.</para></formalpara>

</section>

<section id="category"><title>Category</title>
<para>The &category; argument of the &gettext; and &ngettext;
functions denotes which locale facet the result should depend on.
The default value is <constant>:LC_MESSAGES</constant>.
Other possible values are <constant>:LC_CTYPE</constant>,
<constant>:LC_TIME</constant>, <constant>:LC_COLLATE</constant>,
<constant>:LC_MONETARY</constant>.
The use of these values is useful for users who have a
character/time/collation/money handling set differently from the usual
message handling.
Note that when a &category; argument is used, the message catalog
location depends on the &category;: it will be expected at
<filename>TEXTDOMAINDIR/ll/category/domain.mo</filename>.</para>
</section>

<section id="i18n-example"><title>Example</title>

<para>A non-internationalized program simulating a restaurant dialogue
might look as follows.</para>

<example id="i18n-non-i"><title>prog.lisp</title>
<programlisting>
(setq n (parse-integer (first &args;)))

(format t "~A~%" "'Your command, please?', asked the waiter.")

(format t "~@?~%"
          (if (= n 1) "a piece of cake" "~D pieces of cake")
          n)
</programlisting></example>

<para>After being internationalized, all strings are wrapped in
&gettext; calls, and &ngettext; is used for plurals.
Also, &textdomaindir; is assigned a value; in our case, for simplicity,
the current directory.</para>

<example id="i18n-i"><title>prog.lisp</title>
<programlisting>
(setf (textdomain) "prog")
(setf (textdomaindir "prog") "./")

(setq n (parse-integer (first &args;)))

(format t "~A~%"
          (gettext "'Your command, please?', asked the waiter."))

(format t "~@?~%"
          (ngettext "a piece of cake" "~D pieces of cake" n)
          n)
</programlisting></example>

<para>For ease of reading, it is customary to define an abbreviation
for the &gettext; function.  An underscore is customary.</para>

<example id="i18n-i-abbrev"><title>prog.lisp</title>
<programlisting>
(setf (textdomaindir "prog") "./")
(defun _ (msgid) (gettext msgid "prog"))

(setq n (parse-integer (first &args;)))

(format t "~A~%"
          (_"'Your command, please?', asked the waiter."))

(format t "~@?~%"
          (ngettext "a piece of cake" "~D pieces of cake" n "prog")
          n)
</programlisting></example>

<para>Now the program's maintainer creates a message catalog template
through the command
<screen>
bash$ xgettext -o prog.pot prog.lisp
</screen>
</para>

<note><title>Note</title>
 <para>xgettext version 0.11 or higher is required here.</para></note>

<para>The message catalog template looks roughly like this.</para>

<example id="i18n-pot"><title>prog.pot</title>
<programlisting>
msgid "'Your command, please?', asked the waiter."
msgstr ""

msgid "a piece of cake"
msgid_plural "%d pieces of cake"
msgstr[0] ""
msgstr[1] ""
</programlisting></example>

<para>Then a French translator creates a French message catalog</para>

<example id="i18n-fr-po"><title>prog.fr.po</title>
<programlisting>
msgid ""
msgstr ""
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"

msgid "'Your command, please?', asked the waiter."
msgstr "&laquo;Votre commande, s'il vous plait&raquo;, dit le gar&ccedil;on."

# Les gateaux allemands sont les meilleurs du monde.
msgid "a piece of cake"
msgid_plural "%d pieces of cake"
msgstr[0] "un morceau de gateau"
msgstr[1] "%d morceaux de gateau"
</programlisting></example>

<para>and sends it to the program's maintainer.</para>

<para>The program's maintainer compiles the catalog as follows:

<screen>
bash$ mkdir -p ./fr/LC_MESSAGES
bash$ msgfmt -o ./fr/LC_MESSAGES/prog.mo prog.fr.po
</screen></para>

<para>When a user in a french locale then runs the program

<screen>
bash$ clisp prog.lisp 2
</screen>

she will get the output

<screen>
    &laquo;Votre commande, s'il vous plait&raquo;, dit le gar&ccedil;on.
    2 morceaux de gateau
</screen>
</para>

</section>

</section>

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

 <warning><para>Note that 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>
</simplelist></para>

<para>This is controlled by the &symbol-macro;
 <firstterm>&curr-lang;<indexterm id="curr-lang" significance="preferred">
   <primary id="curr-lang-i"><varname>*CURRENT-LANGUAGE*</varname>
 </primary></indexterm></firstterm>,
 which can be set at run time as well as using <olink targetdoc="man"
 targetptr="opt-lang"><option>-L</option></olink> start-up 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 id="deflang-i"><function>DEFLANGUAGE</function>
 </primary></indexterm></firstterm>:
 <literal role="sexp">(&deflang; &lang-r;)</literal>.
 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;) po-mode.</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 id="def-i-l-i"><function>DEFINTERNATIONAL</function>
 </primary></indexterm></firstterm>:
 <literal role="sexp">(&def-i-l; &symbol-r; &optional-amp;
 (<replaceable>default-language</replaceable> &t;))</literal> and add
 language-dependent values through the macro
 <firstterm>&defloc;<indexterm id="defloc" significance="preferred">
   <primary id="defloc-i"><function>DEFLOCALIZED</function>
 </primary></indexterm></firstterm>:
 <literal role="sexp">(&defloc; &symbol-r; &lang-r;
  <replaceable>value-form</replaceable>)</literal>
 (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 id="localized-i"><function>LOCALIZED</function>
 </primary></indexterm></firstterm>:
 <literal role="sexp">(&localized; &symbol-r; &optional-amp;
  &lang-r;)</literal></para>

</section>

</section>

<section id="encoding"><title>Extensions-1.4. 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 characters that
    can be represented and passed through the I/O channel, and the way
    these characters translate into raw bytes.  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 types.  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.</para>

</section>

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

<variablelist>
<!-- #ifndef UNICODE -->
<varlistentry><term>Platform dependent: Only in &clisp; built
  &without; compile-time flag &unicode;.</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>Platform dependent:
  Only in &clisp; built &with; compile-time flag &unicode;.</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><literal>UCS-2</literal>
   &equiv; <literal>UNICODE-16</literal>
   &equiv; <literal>UNICODE-16-BIG-ENDIAN</literal>,
   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><literal>UNICODE-16-LITTLE-ENDIAN</literal>
    </simpara></listitem>
 <listitem id="charset-UCS-4"><simpara><literal>UCS-4</literal>
   &equiv; <literal>UNICODE-32</literal>
   &equiv; <literal>UNICODE-32-BIG-ENDIAN</literal>,
   the 21-bit &unicode; character set. Every character is represented as
   four bytes.</simpara></listitem>
 <listitem id="charset-UNICODE-32-LITTLE-ENDIAN"><simpara><literal>UNICODE-32-LITTLE-ENDIAN</literal>
 </simpara></listitem>
 <listitem id="charset-UTF-8"><simpara><literal>UTF-8</literal>,
   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><literal>UTF-16</literal>,
   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><literal>UTF-7</literal>,
   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><literal>JAVA</literal>,
   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><literal>ASCII</literal>,
   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><literal>ISO-8859-1</literal>,
   &ascii-iso-ext; Afrikaans, Albanian, Basque, Breton, Catalan,
   Cornish, Danish, Dutch, English, Faeroese, Finnish, French,
   Frisian, Galician, German, Greenlandic, Icelandic, Irish, Italian,
   Latin, Luxemburgish, Norwegian, Portuguese, Raeto-Romanic,
   Scottish, Spanish, and Swedish languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-2"><simpara><literal>ISO-8859-2</literal>,
   &ascii-iso-ext; Croatian, Czech, German, Hungarian, Polish,
   Slovak, Slovenian, and Sorbian languages. </simpara></listitem>
 <listitem id="charset-ISO-8859-3"><simpara><literal>ISO-8859-3</literal>,
   &ascii-iso-ext; Esperanto and Maltese languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-4"><simpara><literal>ISO-8859-4</literal>,
   &ascii-iso-ext; Estonian, Latvian, Lithuanian and Sami (Lappish)
   languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-5"><simpara><literal>ISO-8859-5</literal>,
   &ascii-iso-ext; Bulgarian, Byelorussian, Macedonian, Russian,
   Serbian, and Ukrainian languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-6"><simpara><literal>ISO-8859-6</literal>,
   suitable for the Arabic language.</simpara></listitem>
 <listitem id="charset-ISO-8859-7"><simpara><literal>ISO-8859-7</literal>,
   &ascii-iso-ext; Greek language.</simpara></listitem>
 <listitem id="charset-ISO-8859-8"><simpara><literal>ISO-8859-8</literal>,
      &ascii-iso-ext; Hebrew language (without punctuation).
 </simpara></listitem>
 <listitem id="charset-ISO-8859-9"><simpara><literal>ISO-8859-9</literal>,
   &ascii-iso-ext; Turkish language.</simpara></listitem>
 <listitem id="charset-ISO-8859-10"><simpara><literal>ISO-8859-10</literal>,
   &ascii-iso-ext; Estonian, Icelandic, Inuit (Greenlandic), Latvian,
   Lithuanian, and Sami (Lappish) languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-13"><simpara><literal>ISO-8859-13</literal>,
   &ascii-iso-ext; Estonian, Latvian, Lithuanian, Polish and Sami
   (Lappish) languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-14"><simpara><literal>ISO-8859-14</literal>,
   &ascii-iso-ext; Irish Gaelic, Manx Gaelic, Scottish Gaelic, and
   Welsh languages.</simpara></listitem>
 <listitem id="charset-ISO-8859-15"><simpara><literal>ISO-8859-15</literal>,
   &ascii-iso-ext; ISO-8859-1 languages, with improvements for
   French, Finnish and the Euro.</simpara></listitem>
 <listitem id="charset-ISO-8859-16"><simpara><literal>ISO-8859-16</literal>
   &ascii-iso-ext; Rumanian language.</simpara></listitem>
 <listitem id="charset-KOI8-R"><simpara><literal>KOI8-R</literal>,
   &ascii-iso-ext; Russian language (very popular, especially on the
   internet).</simpara></listitem>
 <listitem id="charset-KOI8-U"><simpara><literal>KOI8-U</literal>,
   &ascii-iso-ext; Ukrainian language (very popular, especially on the
   internet).</simpara></listitem>
<!-- #ifdef GNU_LIBICONV -->
 <listitem id="charset-KOI8-RU"><simpara><literal>KOI8-RU</literal>,
   &ascii-iso-ext; Russian language. &charset-libiconv;</simpara></listitem>
<!-- #endif /* GNU_LIBICONV */ -->
 <listitem><simpara><literal>JIS_X0201</literal>,
   a character set for the Japanese language.</simpara></listitem>
 <listitem id="charset-MAC-ARABIC"><simpara><literal>MAC-ARABIC</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-CENTRAL-EUROPE"><simpara><literal>MAC-CENTRAL-EUROPE</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-CROATIAN"><simpara><literal>MAC-CROATIAN</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-CYRILLIC"><simpara><literal>MAC-CYRILLIC</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-DINGBAT"><simpara><literal>MAC-DINGBAT</literal>,
   a platform specific character set.
 </simpara></listitem>
 <listitem id="charset-MAC-GREEK"><simpara><literal>MAC-GREEK</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-HEBREW"><simpara><literal>MAC-HEBREW</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-ICELAND"><simpara><literal>MAC-ICELAND</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-ROMAN"><simpara><literal>MAC-ROMAN</literal>
   &equiv; <literal>MACINTOSH</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-ROMANIA"><simpara><literal>MAC-ROMANIA</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-SYMBOL"><simpara><literal>MAC-SYMBOL</literal>,
   a platform specific character set.</simpara></listitem>
 <listitem id="charset-MAC-THAI"><simpara><literal>MAC-THAI</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-TURKISH"><simpara><literal>MAC-TURKISH</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-MAC-UKRAINE"><simpara><literal>MAC-UKRAINE</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-CP437"><simpara><literal>CP437</literal>, a DOS oldie,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-CP437-IBM"><simpara><literal>CP437-IBM</literal>,
   an IBM variant of <literal>CP437</literal>.
 </simpara></listitem>
 <listitem id="charset-CP737"><simpara><literal>CP737</literal>, a DOS oldie,
   &ascii-pl-ext;, meant to be suitable for the Greek language.
 </simpara></listitem>
 <listitem id="charset-CP775"><simpara><literal>CP775</literal>, a DOS oldie,
   &ascii-pl-ext;, meant to be suitable for some Baltic languages.
 </simpara></listitem>
 <listitem id="charset-CP850"><simpara><literal>CP850</literal>, a DOS oldie,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-CP852"><simpara><literal>CP852</literal>, a DOS oldie,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-CP852-IBM"><simpara><literal>CP852-IBM</literal>,
   an IBM variant of <literal>CP852</literal>.</simpara></listitem>
 <listitem id="charset-CP855"><simpara><literal>CP855</literal>, a DOS oldie,
   &ascii-pl-ext;, meant to be suitable for the Russian language.
 </simpara></listitem>
 <listitem id="charset-CP857"><simpara><literal>CP857</literal>, a DOS oldie,
   &ascii-pl-ext;, meant to be suitable for the Turkish language.
 </simpara></listitem>
 <listitem id="charset-CP860"><simpara><literal>CP860</literal>, a DOS oldie,
   &ascii-pl-ext;, meant to be suitable for the Portuguese language.
 </simpara></listitem>
 <listitem id="charset-CP860-IBM"><simpara><literal>CP860-IBM</literal>,
   an IBM variant of <literal>CP860</literal>.
 </simpara></listitem>
 <listitem id="charset-CP861"><simpara><literal>CP861</literal>, a DOS oldie,
   &ascii-pl-ext;, meant to be suitable for the Icelandic language.
 </simpara></listitem>
 <listitem id="charset-CP861-IBM"><simpara><literal>CP861-IBM</literal>,
   an IBM variant of <literal>CP861</literal>.
 </simpara></listitem>
 <listitem id="charset-CP862"><simpara><literal>CP862</literal>, a DOS oldie,
   &ascii-pl-ext;, meant to be suitable for the Hebrew language.
 </simpara></listitem>
 <listitem id="charset-CP862-IBM"><simpara><literal>CP862-IBM</literal>,
   an IBM variant of <literal>CP862</literal>.
 </simpara></listitem>
 <listitem id="charset-CP863"><simpara><literal>CP863</literal>, a DOS oldie,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-CP863-IBM"><simpara><literal>CP863-IBM</literal>,
   an IBM variant of <literal>CP863</literal>.
 </simpara></listitem>
 <listitem id="charset-CP864"><simpara><literal>CP864</literal>, a DOS oldie,
   meant to be suitable for the Arabic language.
 </simpara></listitem>
 <listitem id="charset-CP864-IBM"><simpara><literal>CP864-IBM</literal>,
   an IBM variant of <literal>CP864</literal>.
 </simpara></listitem>
 <listitem id="charset-CP865"><simpara><literal>CP865</literal>, a DOS oldie,
   &ascii-pl-ext;, meant to be suitable for some Nordic languages.
 </simpara></listitem>
 <listitem id="charset-CP865-IBM"><simpara><literal>CP865-IBM</literal>,
   an IBM variant of <literal>CP865</literal>.
 </simpara></listitem>
 <listitem id="charset-CP866"><simpara><literal>CP866</literal>, a DOS oldie,
   &ascii-pl-ext;, meant to be suitable for the Russian language.
 </simpara></listitem>
 <listitem id="charset-CP869"><simpara><literal>CP869</literal>, a DOS oldie,
   &ascii-pl-ext;, meant to be suitable for the Greek language.
 </simpara></listitem>
 <listitem id="charset-CP869-IBM"><simpara><literal>CP869-IBM</literal>,
   an IBM variant of <literal>CP869</literal>.
 </simpara></listitem>
 <listitem id="charset-CP874"><simpara><literal>CP874</literal>, a DOS oldie,
   &ascii-pl-ext;, meant to be suitable for the Thai language.
 </simpara></listitem>
 <listitem id="charset-CP874-IBM"><simpara><literal>CP874-IBM</literal>,
   an IBM variant of <literal>CP874</literal>.
 </simpara></listitem>
 <listitem id="charset-WINDOWS-1250"><simpara><literal>WINDOWS-1250</literal>
   &equiv; <literal>CP1250</literal>,
   &ascii-pl-ext;, heavily incompatible with ISO-8859-2.
 </simpara></listitem>
 <listitem id="charset-WINDOWS-1251"><simpara><literal>WINDOWS-1251</literal>
   &equiv; <literal>CP1251</literal>,
   &ascii-pl-ext;, heavily incompatible with ISO-8859-5,
   meant to be suitable for the Russian language.
 </simpara></listitem>
 <listitem id="charset-WINDOWS-1252"><simpara><literal>WINDOWS-1252</literal>
   &equiv; <literal>CP1252</literal>,
   a platform specific extension of the ISO-8859-1 character set.
 </simpara></listitem>
 <listitem id="charset-WINDOWS-1253"><simpara><literal>WINDOWS-1253</literal>
   &equiv; <literal>CP1253</literal>,
   &ascii-pl-ext;, gratuitously incompatible with ISO-8859-7,
   meant to be suitable for the Greek language.
 </simpara></listitem>
 <listitem id="charset-WINDOWS-1254"><simpara><literal>WINDOWS-1254</literal>
   &equiv; <literal>CP1254</literal>,
   a platform specific extension of the ISO-8859-9 character set.
 </simpara></listitem>
<!-- #ifdef GNU_LIBICONV -->
 <listitem id="charset-WINDOWS-1255"><simpara><literal>WINDOWS-1255</literal>
   &equiv; <literal>CP1255</literal>,
   &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><literal>WINDOWS-1256</literal>
   &equiv; <literal>CP1256</literal>,
   &ascii-pl-ext;, meant to be suitable for the Arabic language.
 </simpara></listitem>
 <listitem id="charset-WINDOWS-1257"><simpara><literal>WINDOWS-1257</literal>
   &equiv; <literal>CP1257</literal>,
   &ascii-pl-ext;.</simpara></listitem>
<!-- #ifdef GNU_LIBICONV -->
 <listitem id="charset-WINDOWS-1258"><simpara><literal>WINDOWS-1258</literal>
   &equiv; <literal>CP1258</literal>,
   &ascii-pl-ext;, meant to be suitable for the Vietnamese language.
   &charset-glibc-libiconv;</simpara></listitem>
<!-- #endif /* GNU_LIBICONV */ -->
 <listitem id="charset-HP-ROMAN8"><simpara><literal>HP-ROMAN8</literal>,
   &ascii-pl-ext;.</simpara></listitem>
 <listitem id="charset-NEXTSTEP"><simpara><literal>NEXTSTEP</literal>,
   &ascii-pl-ext;.</simpara></listitem>
<!-- #ifdef GNU_LIBICONV -->
 <listitem id="charset-EUC-JP"><simpara><literal>EUC-JP</literal>,
   a multibyte character set for the Japanese language.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-SHIFT-JIS"><simpara><literal>SHIFT-JIS</literal>,
   a multibyte character set for the Japanese language.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-CP932"><simpara><literal>CP932</literal>,
   a Microsoft variant of <literal>SHIFT-JIS</literal>.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ISO-2022-JP"><simpara><literal>ISO-2022-JP</literal>,
   a stateful 7-bit multibyte character set for the Japanese language.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ISO-2022-JP-2"><simpara><literal>ISO-2022-JP-2</literal>,
   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><literal>ISO-2022-JP-1</literal>,
   a stateful 7-bit multibyte character set for the Japanese language.
   &charset-libiconv;</simpara></listitem>
 <listitem id="charset-EUC-CN"><simpara><literal>EUC-CN</literal>,
   a multibyte character set for simplified Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-HZ"><simpara><literal>HZ</literal>,
   a stateful 7-bit multibyte character set for simplified Chinese.
   &charset-libiconv;</simpara></listitem>
 <listitem id="charset-GBK"><simpara><literal>GBK</literal>,
   a multibyte character set for Chinese,
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-CP936"><simpara><literal>CP936</literal>,
   a Microsoft variant of <literal>GBK</literal>.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-GB18030"><simpara><literal>GB18030</literal>,
   a multibyte character set for Chinese,
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-EUC-TW"><simpara><literal>EUC-TW</literal>,
   a multibyte character set for traditional Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-BIG5"><simpara><literal>BIG5</literal>,
   a multibyte character set for traditional Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-CP950"><simpara><literal>CP950</literal>,
   a Microsoft variant of <literal>BIG5</literal>.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-BIG5-HKSCS"><simpara><literal>BIG5-HKSCS</literal>,
   a multibyte character set for traditional Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ISO-2022-CN"><simpara><literal>ISO-2022-CN</literal>,
   a stateful 7-bit multibyte character set for Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ISO-2022-CN-EXT"><simpara><literal>ISO-2022-CN-EXT</literal>,
   a stateful 7-bit multibyte character set for Chinese.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-EUC-KR"><simpara><literal>EUC-KR</literal>,
   a multibyte character set for Korean.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-CP949"><simpara><literal>CP949</literal>,
   a Microsoft variant of <literal>EUC-KR</literal>.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ISO-2022-KR"><simpara><literal>ISO-2022-KR</literal>,
   a stateful 7-bit multibyte character set for Korean.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-JOHAB"><simpara><literal>JOHAB</literal>,
   a multibyte character set for Korean used mostly on &dos;.
   &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-ARMSCII-8"><simpara><literal>ARMSCII-8</literal>,
   &ascii-iso-ext; Armenian. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-GEORGIAN-ACADEMY"><simpara><literal>GEORGIAN-ACADEMY</literal>,
   &ascii-iso-ext; Georgian. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-GEORGIAN-PS"><simpara><literal>GEORGIAN-PS</literal>,
   &ascii-iso-ext; Georgian. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-TIS-620"><simpara><literal>TIS-620</literal>,
   &ascii-iso-ext; Thai. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-MULELAO-1"><simpara><literal>MULELAO-1</literal>,
   &ascii-iso-ext; Laotian. &charset-libiconv;</simpara></listitem>
 <listitem id="charset-CP1133"><simpara><literal>CP1133</literal>,
   &ascii-iso-ext; Laotian. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-VISCII"><simpara><literal>VISCII</literal>,
   &ascii-iso-ext; Vietnamese. &charset-glibc-libiconv;</simpara></listitem>
 <listitem id="charset-TCVN"><simpara><literal>TCVN</literal>,
   &ascii-iso-ext; Vietnamese. &charset-glibc-libiconv;</simpara></listitem>
<!-- #endif /* GNU_LIBICONV */ -->
</orderedlist>

<!-- #ifdef /* HAVE_ICONV */ -->
<variablelist>
<varlistentry id="iconv"><term>Platform dependent: 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</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 &gnu; systems (such as &gnu;/&linux; and &gnu;/&hurd;)
 and on systems with &libiconv; you get this list by calling the
 <emphasis>program</emphasis> &iconv-u;: <command>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 &clisp-list; and a
 future &clisp; version will use &iconv; on your system.</simpara>

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

<!-- #endif /* 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 line terminator mode is relevant only for output (writing to a
 &file-pipe-socket;).  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
  <literal role="sexp">(&make-encoding; &key-amp; :CHARSET
     :LINE-TERMINATOR :INPUT-ERROR-ACTION :OUTPUT-ERROR-ACTION)</literal>
 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>Platform dependent: Only in &clisp; built
 &with; compile-time flag &unicode;.</subtitle>

<para>The function <literal role="sexp">(&enc-charset; &encoding-r;)</literal>
 returns the charset of the &encoding-r;, as a &symbol-t; or a &string-t;.
 Note that <literal role="sexp">(&string; (&enc-charset;
 &encoding-r;))</literal> is not necessarily a valid MIME name.</para>

</section>

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

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

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

<!-- #ifdef UNICODE -->
<variablelist>
<varlistentry><term>Platform dependent: Only in &clisp; built
  &with; compile-time flag &unicode;.</term>
<listitem><simpara>The following are &symbol-macro; places.</simpara>
<variablelist>
<varlistentry id="path-enc"><term>&path-enc;</term>
 <listitem><simpara>is the encoding used for pathnames in the file
 system. Normally, this is a 1:1 encoding.  Its &line-term; mode is ignored.
 </simpara></listitem></varlistentry>
<varlistentry id="term-enc"><term>&term-enc;</term>
 <listitem><simpara>is the encoding used for communication with the
  terminal, in particular by &terminal-io-var;.
 </simpara></listitem></varlistentry>
<varlistentry id="misc-enc"><term>&misc-enc;</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(HAVE_AFFI) || defined(DYNAMIC_FFI) -->
<varlistentry id="foreign-enc"><term>&foreign-enc;</term>
 <listitem><simpara>is the encoding for characters and strings passed
 through the &ffi-pac; (some plaforms only).
 Its value must be a 1:1 encoding, i.e., an encoding in which every
 character is represented by one byte.
</simpara></listitem></varlistentry>
<!-- #endif -->
</variablelist></listitem></varlistentry>
</variablelist>
<!-- #endif -->

<para>The default encoding objects are initialized as described in
 <olink targetdoc="man" targetptr="opt-enc"/></para>

</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><literal role="sexp"
    >(<function>EXT:CONVERT-STRING-FROM-BYTES</function>
      <replaceable>byte-vector</replaceable> &encoding-r;
      &key-amp; &start-k; &end-k;)</literal></term>
 <listitem><simpara>converts the subsequence of
  <replaceable>byte-vector</replaceable> 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><literal role="sexp"
    >(<function>EXT:CONVERT-STRING-TO-BYTES</function>
      &string-r; &encoding-r; &key-amp; &start-k; &end-k;)</literal></term>
 <listitem><simpara>converts the subsequence of &string-r; from
  &start-r; to &end-r; to a &unsigned-byte-vec;,
  according to the given &encoding-r;, and returns the resulting byte
  vector.</simpara></listitem></varlistentry>

</variablelist>

</section>
</section>

<section id="clos-stream">
  <title>Extensions-1.5. Defining new kinds of Streams</title>

<para>Two mechanisms are supported for creating new streams with
user-defined behavior:
<itemizedlist>
 <listitem><simpara>You can create a new subclass of &fu-st; and define
  methods for the elementary stream operations on it.  These generic
  functions all have a name starting with the prefix "stream-".
  </simpara></listitem>
 <listitem><simpara>You can create a new subclass of
  <classname>GSTREAM:GENERIC-STREAM-CONTROLLER</classname> and define
  methods for the elementary stream operations on it.  These generic
  functions all have a name starting with the prefix
  "generic-stream-".  The stream itself is a different object, created
  using the function <function>gstream:make-generic-stream</function>.
  </simpara></listitem>
</itemizedlist></para>

<para>The <classname>FUNDAMENTAL-STREAM</classname> API is based on the
 &gray-streams; proposal by David N. Gray and is supported by most &cl;
 implementations currently in use.
 The <classname>GSTREAM:GENERIC-STREAM-CONTROLLER</classname>
 API is &clisp;-specific and is now obsolete.</para>

<section id="gray"><title>Gray streams</title>

<para>This interface permits the definition of new classes of streams,
and programming their behavior by defining methods for the elementary
stream operations.  It is based on the proposal &gray-streams; of David
N. Gray to X3J13.</para>

<para>All symbols defined by this interface, starting with the prefix
 "fundamental-" or "stream-", are exported from the package
 &gray-pac; and re-exported from &ext-pac;.</para>

<variablelist><title>Defined classes</title>
 <varlistentry id="fu-st"><term>&fu-st;</term>
  <listitem><simpara>This is a superclass of all user-defined streams.
   It is a subclass of &stream-t; and of &standard-object-t;.
   Its metaclass is &standard-class;.</simpara></listitem></varlistentry>
 <varlistentry id="fu-st-in"><term>&fu-st-in;</term>
  <listitem><simpara>This is a superclass of all user-defined &in-s;s.
   It is a subclass of &fu-st;.  The built-in function &input-stream-p;
   returns true on instances of this class.  This means that when you
   define a new stream class capable of doing input, you have to make it
   a subclass of &fu-st-in;.</simpara></listitem></varlistentry>
 <varlistentry id="fu-st-out"><term>&fu-st-out;</term>
  <listitem><simpara>This is a superclass of all user-defined &out-s;s.
   It is a subclass of &fu-st;.  The built-in function &output-stream-p;
   returns true on instances of this class.  This means that when you
   define a new stream class capable of doing output, you have to make
   it a subclass of &fu-st-out;.</simpara></listitem></varlistentry>
 <varlistentry id="fu-st-char"><term>&fu-st-char;</term>
  <listitem><simpara>This is a superclass of all user-defined streams
   whose &stream-element-type; is &character-t;.  It is a subclass of
   &fu-st;.  It defines a method on &stream-element-type; that returns
   &character-t;.</simpara></listitem></varlistentry>
 <varlistentry id="fu-st-bin"><term>&fu-st-bin;</term>
  <listitem><simpara>This is a superclass of all user-defined streams
   whose &stream-element-type; is a subtype of &integer-t;.  It is a
   subclass of &fu-st;.  When you define a subclass of &fu-st-bin;,
   you have to provide a method on &stream-element-type;.
  </simpara></listitem></varlistentry>
 <varlistentry>
    <term><classname>GRAY:FUNDAMENTAL-CHARACTER-INPUT-STREAM</classname></term>
  <listitem><simpara>This is a convenience class inheriting from both
   &fu-st-char; and &fu-st-in;.</simpara></listitem></varlistentry>
 <varlistentry>
   <term><classname>GRAY:FUNDAMENTAL-CHARACTER-OUTPUT-STREAM</classname></term>
  <listitem><simpara>This is a convenience class inheriting from both
   &fu-st-char; and &fu-st-out;.</simpara></listitem></varlistentry>
 <varlistentry>
    <term><classname>GRAY:FUNDAMENTAL-BINARY-INPUT-STREAM</classname></term>
  <listitem><simpara>This is a convenience class inheriting from both
   &fu-st-bin; and &fu-st-in;.</simpara></listitem></varlistentry>
 <varlistentry>
    <term><classname>GRAY:FUNDAMENTAL-BINARY-OUTPUT-STREAM</classname></term>
  <listitem><simpara>This is a convenience class inheriting from both
   &fu-st-bin; and &fu-st-out;.</simpara></listitem></varlistentry>
</variablelist>

<variablelist><title>General generic functions defined on streams</title>
 <varlistentry><term><literal role="sexp">(&stream-element-type;
    &stream-r;)</literal></term>
  <listitem><simpara>Returns the stream's element type, normally a
   subtype of &character-t; or &integer-t;.</simpara>
  <simpara>The method for &fu-st-char; returns &character-t;.
  </simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp">((&setf; &stream-element-type;)
    <replaceable>new-element-type</replaceable> &stream-r;)</literal></term>
  <listitem><simpara>Changes the stream's element type.</simpara>
   <simpara>The default method &signal;s an &error-t;.</simpara>
   <simpara>This function is a &clisp; extension (see <xref
    linkend="stream-eltype"/>).</simpara>
   </listitem></varlistentry>
 <varlistentry><term><literal role="sexp">(&close;
    &stream-r; &key-amp; &abort-k;)</literal></term>
  <listitem><simpara>Closes the stream and flushes any associated buffers.
   </simpara><simpara>When you define a primary method on this
    function, do not forget to &call-next-method;.
  </simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp">(&open-stream-p;
    &stream-r;)</literal></term>
  <listitem><simpara>Returns true before the stream has been closed, and
    &nil; after the stream has been closed.</simpara>
   <simpara>You do not need to add methods to this function.</simpara>
   </listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-POSITION</function>
    &stream-r; <replaceable>position</replaceable>)</literal></term>
  <listitem><simpara>Just like &file-position;, but &nil;
    <replaceable>position</replaceable> means inquire.</simpara>
   &need-defmethod;</listitem></varlistentry>
</variablelist>

<variablelist><title>generic functions for character input</title>
 <varlistentry id="st-rc"><term><literal
    role="sexp">(&st-rc; &stream-r;)</literal></term>
  <listitem><simpara>If a character was pushed back using &st-uc;,
   returns and consumes it.  Otherwise returns and consumes the next
   character from the stream. Returns &eof-k; if the &eos; is reached.
   </simpara>&need-defmethod;</listitem></varlistentry>
 <varlistentry id="st-uc"><term><literal
    role="sexp">(&st-uc; &stream-r; &ch-r;)</literal></term>
  <listitem><simpara>Pushes &ch-r;, which must be the last character
   read from the &stream-r;, back onto the front of the &stream-r;.
   </simpara>&need-defmethod;</listitem></varlistentry>
 <varlistentry id="st-rcnh"><term><literal
    role="sexp">(&st-rcnh; &stream-r;)</literal></term>
  <listitem><simpara>Returns a character or &eof-k;, like &st-rc;, if
   that would return immediately.  If &st-rc;'s value is not available
   immediately, returns &nil; instead of waiting.</simpara><simpara>
   The default method simply calls &st-rc;; this is sufficient for streams
   whose &st-rc; method never blocks.</simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
   >(<function>GRAY:STREAM-PEEK-CHAR</function> &stream-r;)</literal></term>
  <listitem><simpara>If a character was pushed back using &st-uc;,
   returns it.  Otherwise returns the next character from the stream,
   avoiding any side effects &st-rc; would do.  Returns &eof-k; if the
   &eos; is reached.</simpara>
  <simpara>The default method calls &st-rc; and &st-uc;; this is
   sufficient for streams whose &st-rc; method has no
   side-effects.</simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
   >(<function>GRAY:STREAM-LISTEN</function> &stream-r;)</literal></term>
  <listitem><simpara>If a character was pushed back using &st-uc;,
   returns it.  Otherwise returns the next character from the stream, if
   already available.  If no character is available immediately, or if
   &eos; is reached, returns &nil;.</simpara>
  <simpara>The default method calls &st-rcnh; and &st-uc;; this is
   sufficient for streams whose &st-rc; method has no
   side-effects.</simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-READ-CHAR-WILL-HANG-P</function>
                 &stream-r;)</literal></term>
  <listitem><simpara>Returns &nil; if &st-rc; will return immediately.
   Otherwise it returns true.</simpara>
  <simpara>The default method calls &st-rcnh; and &st-uc;; this is
   sufficient for streams whose &st-rc; method has no side-effects.</simpara>
  <simpara>This function is a &clisp; extension (see &rcwhp;).</simpara>
  </listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
   >(<function>GRAY:STREAM-READ-CHAR-SEQUENCE</function> &stream-r;
   &sequence-r; &optional-amp; [&start-r; [&end-r;]])</literal></term>
  <listitem><simpara>Fills the subsequence of &sequence-r; specified by
   &start-k; and &end-k; with characters consecutively read from &stream-r;.
   Returns the index of the first element of &sequence-r; that was not
   updated (&areq; &end-r;, or &lst; &end-r; if the stream reached its end).
   </simpara>
  <simpara>&sequence-r; is an &array-t; of &character-t;s, i.e. a &string-t;.
   &start-r; is a nonnegative &integer-t; and defaults to &zero;.
   &end-r; is a nonnegative &integer-t; or &nil; and defaults to &nil;,
   which stands for <literal role="sexp">(&length; &sequence-r;)</literal>.
  </simpara><simpara>The default method repeatedly calls &st-rc;; this
   is always sufficient if speed does not matter.</simpara>
  <simpara>This function is a &clisp; extension (see
   &rd-ch-seq;).</simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
   >(<function>GRAY:STREAM-READ-LINE</function> &stream-r;)</literal></term>
  <listitem><simpara>Reads a line of characters, and return two values:
   the line (a &string-t;, without the terminating &nl-s; character),
   and a &boolean-t; value which is true if the line was terminated by
   &eos; instead of &nl-s;.</simpara>
  <simpara>The default method repeatedly calls &st-rc;; this
   is always sufficient.</simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-CLEAR-INPUT</function>
                 &stream-r;)</literal></term>
  <listitem><simpara>Clears all pending interactive input from the
   &stream-r;, and returns true if some pending input was removed.</simpara>
  <simpara>The default method does nothing and returns &nil;; this is
   sufficient for non-interactive streams.</simpara></listitem></varlistentry>
</variablelist>

<variablelist><title>generic functions for character output</title>
 <varlistentry id="st-wc"><term><literal
    role="sexp">(&st-wc; &stream-r; &ch-r;)</literal></term>
  <listitem><simpara>Writes &ch-r;.
   </simpara>&need-defmethod;</listitem></varlistentry>
 <varlistentry id="st-lc"><term><literal
    role="sexp">(&st-lc; &stream-r;)</literal></term>
  <listitem><simpara>Returns the column number where the next character
   would be written (&zero; stands for the first column),
    or &nil; if that is not meaningful for this stream.
   </simpara>&need-defmethod;</listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-START-LINE-P</function>
                 &stream-r;)</literal></term>
  <listitem><simpara>Returns true if the next character would be
   written at the start of a new line.</simpara>
  <simpara>The default method calls &st-lc; and compares its result with
   0; this is sufficient for streams whose &st-lc; never returns &nil;.
  </simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-WRITE-CHAR-SEQUENCE</function>
                 &stream-r; &sequence-r;
                 &optional-amp; [&start-r; [&end-r;]])</literal></term>
  <listitem><simpara>Outputs the subsequence of &sequence-r; specified
   by &start-k; and &end-k; to &stream-r;.</simpara>
  <simpara>&sequence-r; is an &array-t; of &character-t;s, i.e. a &string-t;.
   &start-r; is a nonnegative &integer-t; and defaults to 0.
   &end-r; is a nonnegative integer or &nil; and defaults to &nil;,
   which stands for <literal role="sexp">(&length; &sequence-r;)</literal>.
  </simpara><simpara>The default method repeatedly calls &st-wc;; this
   is always sufficient if speed does not matter.
  </simpara><simpara>This function is a &clisp; extension
   (see &wr-ch-seq;).</simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-WRITE-STRING</function>
                 &stream-r; &string-r;
                 &optional-amp; [&start-r; [&end-r;]])</literal></term>
  <listitem><simpara>Outputs the subsequence of &string-r; specified by
   &start-k; and &end-k; to &stream-r;.  Returns &string-r;.</simpara>
   <simpara>&string-r; is a string.  &start-r; is a nonnegative integer
   and default to 0.  &end-r; is a nonnegative integer or &nil; and
   defaults to &nil;, which stands for <literal role="sexp">(&length;
   &string-r;)</literal>.</simpara>
  <simpara>The default method calls
   <function>GRAY:STREAM-WRITE-CHAR-SEQUENCE</function>;
   this is always sufficient.</simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-TERPRI</function>
                 &stream-r;)</literal></term>
  <listitem><simpara>Outputs a &nl-s; character.</simpara>
  <simpara>The default method calls &st-wc;; this is always
   sufficient.</simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-FRESH-LINE</function>
                 &stream-r;)</literal></term>
  <listitem><simpara>Possibly outputs a &nl-s; character, so as to ensure
   that the next character would be written at the start of a new line.
   Returns true if it did output a &nl-s; character.</simpara>
  <simpara>The default method calls
   <function>GRAY:STREAM-START-LINE-P</function> and then
   <function>GRAY:STREAM-TERPRI</function> if necessary; this is always
   sufficient.</simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-FINISH-OUTPUT</function>
                 &stream-r;)</literal></term>
  <listitem><simpara>Ensures that any buffered output has reached its
   destination, and then returns.</simpara>
  <simpara>The default method does nothing.</simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-FORCE-OUTPUT</function>
                 &stream-r;)</literal></term>
  <listitem><simpara>Brings any buffered output on its way towards its
   destination, and returns without waiting until it has reached its
   destination.</simpara>
  <simpara>The default method does nothing.</simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-CLEAR-OUTPUT</function>
                 &stream-r;)</literal></term>
  <listitem><simpara>Attempts to discard any buffered output which has
   not yet reached its destination.</simpara>
  <simpara>The default method does nothing.</simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-ADVANCE-TO-COLUMN</function>
                 &stream-r; <replaceable>column</replaceable>)</literal></term>
  <listitem><simpara>Ensures that the next character will be written at
   <replaceable>column</replaceable> at least.</simpara>
  <simpara>The default method outputs an appropriate amount of space
   characters; this is sufficient for non-proportional output.</simpara>
  </listitem></varlistentry>
</variablelist>

<variablelist><title>generic functions for binary input</title>
 <varlistentry id="st-rb"><term><literal
    role="sexp">(&st-rb; &stream-r;)</literal></term>
  <listitem><simpara>Returns and consumes the next integer from the
   stream. Returns &eof-k; if the &eos; is reached.</simpara>
   &need-defmethod;</listitem></varlistentry>
 <varlistentry id="st-rbla"><term><literal
    role="sexp">(&st-rbla; &stream-r;)</literal></term>
  <listitem><simpara>To be called only if &stream-r;'s
   &stream-element-type; is &unsigned-byte-8; or &signed-byte-8;.
   Returns &t; if &st-rb; would return immediately with an
   &integer-t; result.  Returns &eof-k; if the &eos; is already
   known to be reached.  If &st-rb;'s value is not available
   immediately, returns &nil; instead of waiting.</simpara>
   &need-defmethod;<simpara>This function is a &clisp; extension (see
   &rbla;).</simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-READ-BYTE-WILL-HANG-P</function>
                 &stream-r;)</literal></term>
  <listitem><simpara>To be called only if &stream-r;'s
   &stream-element-type; is &unsigned-byte-8; or &signed-byte-8;.
   Returns &nil; if &st-rb; will return immediately.
   Otherwise it returns true.</simpara>
   <simpara>The default method calls &st-rbla;; this is always sufficient.
   </simpara><simpara>This function is a &clisp; extension (see &rbwhp;).
 </simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-READ-BYTE-NO-HANG</function>
                 &stream-r;)</literal></term>
  <listitem><simpara>To be called only if &stream-r;'s
   &stream-element-type; is &unsigned-byte-8; or &signed-byte-8;.
   Returns an &integer-t; or &eof-k;, like &st-rb;, if that would
   return immediately.  If &st-rb;'s value is not available immediately,
   returns &nil; instead of waiting.</simpara>
   <simpara>The default method calls &st-rb; if &st-rbla; returns true;
    this is always sufficient.</simpara>
   <simpara>This function is a &clisp; extension (see &rbnh;).
 </simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-READ-BYTE-SEQUENCE</function>
                 &stream-r; &sequence-r; &optional-amp;
                 [&start-r; [&end-r; [&no-hang;]]])</literal></term>
  <listitem><simpara>Fills the subsequence of &sequence-r; specified by
   &start-k; and &end-k; with integers consecutively read from &stream-r;.
   Returns the index of the first element of &sequence-r; that was not
   updated (&areq; &end-r;, or &lst; &end-r; if the stream reached its end).
   </simpara>
  <simpara>&sequence-r; is an &array-t; of &integer-t;s.
   &start-r; is a nonnegative &integer-t; and defaults to 0.
   &end-r; is a nonnegative &integer-t; or &nil; and defaults to &nil;,
   which stands for <literal role="sexp">(&length; &sequence-r;)</literal>.
  </simpara><simpara>The default method repeatedly calls &st-rb;; this
   is always sufficient if speed does not matter.</simpara>
  <simpara>This function is a &clisp; extension (see
   &rd-by-seq;).</simpara></listitem></varlistentry>
</variablelist>

<variablelist><title>generic functions for binary output</title>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-WRITE-BYTE</function>
                 &stream-r; &int-r;)</literal></term>
  <listitem><simpara>Writes &int-r;.</simpara>
   &need-defmethod;</listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>GRAY:STREAM-WRITE-BYTE-SEQUENCE</function>
                 &stream-r; &sequence-r; &optional-amp;
                 [&start-r; [&end-r; [&no-hang;]]])</literal></term>
  <listitem><simpara>Outputs the subsequence of &sequence-r; specified
   by &start-k; and &end-k; to &stream-r;</simpara>
  <simpara>&sequence-r; is an &array-t; of &integer-t;s.
   &start-r; is a nonnegative &integer-t; and defaults to 0.
   &end-r; is a nonnegative &integer-t; or &nil; and defaults to &nil;,
   which stands for <literal role="sexp">(&length; &sequence-r;)</literal>.
  </simpara><simpara>The default method repeatedly calls
   <function>GRAY:STREAM-WRITE-BYTE</function>; this is always
   sufficient if speed does not matter.</simpara>
  <simpara>This function is a &clisp; extension (see
   &wr-by-seq;).</simpara></listitem></varlistentry>
</variablelist>

</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><literal
    role="sexp">(<function>gstream:make-generic-stream</function>
                 <replaceable>controller</replaceable>)</literal></term>
  <listitem><simpara>returns a generic stream.
  </simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>gstream:generic-stream-controller</function>
                 &stream-r;)</literal></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><literal
    role="sexp">(<function>gstream:generic-stream-p</function>
                 &stream-r;)</literal></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-<replaceable>xyz</replaceable></function>
 corresponds to the &cl; function
 <function><replaceable>xyz</replaceable></function>.  They all take a
 controller and some number of arguments.</para>

<variablelist>
 <varlistentry><term><literal
    role="sexp">(<function>gstream:generic-stream-read-char</function>
                 <replaceable>controller</replaceable>)</literal></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><literal
    role="sexp">(<function>gstream:generic-stream-peek-char</function>
                 <replaceable>controller</replaceable>)</literal></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><literal
    role="sexp">(<function>gstream:generic-stream-read-byte</function>
                 <replaceable>controller</replaceable>)</literal></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><literal role="sexp"
   >(<function>gstream:generic-stream-read-char-will-hang-p</function>
     <replaceable>controller</replaceable>)</literal></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><literal
    role="sexp">(<function>gstream:generic-stream-write-char</function>
                 <replaceable>controller</replaceable> &ch-r;)</literal></term>
  <listitem><simpara>The first argument is the controller object.
   The second argument is the character to be written.
  </simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>gstream:generic-stream-write-byte</function>
                 <replaceable>controller</replaceable>
                 <replaceable>by</replaceable>)</literal></term>
  <listitem><simpara>The first argument is the controller object.
   The second argument is the integer to be written.
  </simpara></listitem></varlistentry>
 <varlistentry><term><literal
    role="sexp">(<function>gstream:generic-stream-write-string</function>
                 <replaceable>controller</replaceable>
                 &string-r; &start-r; &len-r;)</literal></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><literal
    role="sexp">(<function>gstream:generic-stream-clear-input</function>
                 <replaceable>controller</replaceable>)</literal></term>
  <term><literal role="sexp"
   >(<function>gstream:generic-stream-clear-output</function>
     <replaceable>controller</replaceable>)</literal></term>
  <term><literal role="sexp"
   >(<function>gstream:generic-stream-finish-output</function>
     <replaceable>controller</replaceable>)</literal></term>
  <term><literal role="sexp"
   >(<function>gstream:generic-stream-force-output</function>
     <replaceable>controller</replaceable>)</literal></term>
  <term><literal role="sexp"
   >(<function>gstream:generic-stream-close</function>
     <replaceable>controller</replaceable>)</literal></term>
  <listitem><simpara>Take one argument, the controller object.
 </simpara></listitem></varlistentry>
</variablelist>
<!-- #endif -->

</section>
</section>


<section id="weak"><title>Extensions-1.6. 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>
<varlistentry><term><literal
   role="sexp">(<function>EXT:MAKE-WEAK-POINTER</function>
   &value-r;)</literal></term>
 <listitem><simpara>returns a &fresh; weak pointer referring to
  &value-r;.</simpara></listitem></varlistentry>
<varlistentry><term><literal
   role="sexp">(<function>EXT:WEAK-POINTER-P</function>
   &object-r;)</literal></term>
 <listitem><simpara>returns true if the &object-r; is of type
   &weak-pointer;.</simpara></listitem></varlistentry>
<varlistentry><term><literal
    role="sexp">(<function>EXT:WEAK-POINTER-VALUE</function>
   <replaceable>weak-pointer</replaceable>)</literal></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>&clisp; also has <link linkend="make-hash">weak</link>
 &hash-table-t;.</para>

</section>


<section id="final"><title>Extensions-1.7. Finalization</title>

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

<para>Calling
 <literal role="sexp">(&finalize; &object-r; &func-r;
                       <replaceable>guardian</replaceable>)</literal>
 has a similar effect, but only as long as the
 <replaceable>guardian</replaceable> has not been &gc;ed:
 when &object-r; is being &gc;ed,
 <literal role="sexp">(&funcall; &func-r; &object-r;
                       <replaceable>guardian</replaceable>)</literal>
 will be executed.
 If the <replaceable>guardian</replaceable> 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 <replaceable>guardian</replaceable>) enter
  the "arena of live Lisp objects" again.</para></note>

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

</section>


<section id="prompt"><title>Extensions-1.8. 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 during
 <link linkend="debugger">debugging</link> (after &break; or &error;),
 and <quote>step</quote>, which appears only during &step;ping.
 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 <prompt>"Step n&nbsp;"</prompt>,
     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 <prompt>"Break n&nbsp;"</prompt>,
     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 <prompt>"package[n]"</prompt>
     where &pack-r; is the shortest (nick)name (as returned by
     &package-short-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 <prompt>&gt;&nbsp;</prompt>.
</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-short-name"><term>&package-short-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>Extensions-1.9. Maximum ANSI CL compliance</title>

<para>Some &ansi-cl; features are turned off by default for backwards
 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>

<itemizedlist>
 <listitem><simpara>Setting &pathprint; 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>
</itemizedlist>

<para>Note that if you run &clisp; with the &ansi-opt; 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 &ansi-opt;
 (regardless whether you actually supply the &ansi-opt; switch).
 You can always set the &symbol-macro; &ansi; to &nil;, or invoke
 &clisp; with the &traditional-opt; switch, reversing the above
 settings, i.e.,</para>

<itemizedlist>
 <listitem><simpara>Setting &pathprint; 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>
</itemizedlist>

</section>


<section id="macros3"><title>Extensions-1.10. Additional Fancy Macros</title>

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

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

<formalpara 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>
 (letf (((values a b) form)) ...)
</programlisting>

is equivalent to

<programlisting>
 (multiple-value-bind (a b) form ...)
</programlisting>

while

<programlisting>
(letf (((first l) 7)) ...)
</programlisting>

is approximately equivalent to

<programlisting>
 (&let-star; ((#:g1 l) (#:g2 (first #:g1)))
   (&unwind-protect; (&progn; (&setf; (first #:g1) 7) ...)
      (&setf; (first #:g1) #:g2)))
</programlisting>
</para></formalpara>

<formalpara id="with-collect">
     <title>Macro <function>EXT:WITH-COLLECT</function></title>
<para>Similar to the &loop;'s
 <ulink url="&clhs;/Body/sec_6-1-3.html"><constant>collect</constant></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>
 (ext:with-collect (c0 c1)
   (dotimes (i 10) (if (oddp i) (c0 i) (c1 i))))
</programlisting>

returns two lists <literal role="sexp">(1 3 5 7 9)</literal> and
<literal role="sexp">(0 2 4 6 8)</literal> as &mul-val;.
</para></formalpara>

<formalpara 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>
 (with-gensyms ("FOO-" bar baz zot) ...)
</programlisting>
expands to
<programlisting>
 (let ((bar (gensym "FOO-BAR-"))
       (baz (gensym "FOO-BAZ-"))
       (zot (gensym "FOO-ZOT-")))
   ...)
</programlisting>
</para></formalpara>

<formalpara id="remove-plist">
     <title>Function <function>EXT:REMOVE-PLIST</function></title>
<para>Similar to &remove; and &remf;, this function removes some
 properties from a property list.  It is non-destructve and thus can be
 used on &rest-amp; arguments to remove some keyword parameters, e.g.,
<programlisting>
 (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></formalpara>

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

</section>

<section id="customize">
  <title>Extensions-1.11. Customizing &clisp; behavior.</title>

<para>The user-customizable variables are located in the package
 &custom-pac; and thus can be listed using
 <literal role="sexp">(&apropos; "" "CUSTOM")</literal>:
 <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><varname>CUSTOM:*CLHS-ROOT-DEFAULT*</varname></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>&dev-prefix;</member>
  <member>&editor;</member>
  <member><varname>CUSTOM:*ERROR-HANDLER*</varname></member>
  <member><varname>CUSTOM:*EVALHOOK*</varname></member>
  <member>&flocont;</member>
  <member>&foreign-enc;</member>
  <member><varname>CUSTOM:*INSPECT-BROWSER*</varname></member>
  <member><varname>CUSTOM:*INSPECT-FRONTEND*</varname></member>
  <member><varname>CUSTOM:*INSPECT-LENGTH*</varname></member>
  <member><varname>CUSTOM:*INSPECT-PRINT-LENGTH*</varname></member>
  <member><varname>CUSTOM:*INSPECT-PRINT-LEVEL*</varname></member>
  <member><varname>CUSTOM:*INSPECT-PRINT-LINES*</varname></member>
  <member><varname>CUSTOM:*LIB-DIRECTORY*</varname></member>
  <member>&load-comp;</member>
  <member>&load-echo;</member>
  <member>&load-lpt-db;</member>
  <member>&load-obs;</member>
  <member>&load-paths;</member>
  <member>&pathmerge;</member>
  <member>&misc-enc;</member>
  <member><varname>CUSTOM:*PACKAGE-TASKS-TREAT-SPECIALLY*</varname></member>
  <member>&parsename;</member>
  <member>&parsedot;</member>
  <member>&path-enc;</member>
  <member>&ppr-first-newline;</member>
  <member>&pr-closure;</member>
  <member>&pr-indent;</member>
  <member>&pathprint;</member>
  <member><varname>CUSTOM:*PRINT-PRETTY-FILL*</varname></member>
  <member>&pr-rpars;</member>
  <member><varname>CUSTOM:*PRINT-SYMBOLS-LONG*</varname></member>
  <member>&prompt-body;</member>
  <member>&prompt-break;</member>
  <member>&prompt-finish;</member>
  <member>&prompt-start;</member>
  <member>&prompt-step;</member>
  <member>&count-ansi;</member>
  <member>&source-types;</member>
  <member>&suppress-check-redef;</member>
  <member>&sys-pack-list;</member>
  <member>&term-enc;</member>
  <member>&trace-indent;</member>
  <member><varname>CUSTOM:*USER-MAIL-ADDRESS*</varname></member>
  <member>&warn-fpc;</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-file; 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-file;, compile and load
 it, and then save the &mem-image;.
 Finally, you can create an <quote>RC</quote> (run control) file which
 is loaded whenever &clisp; is started (see the documentation for option
 <olink targetdoc="man" targetptr="opt-norc"><option>-norc</option></olink>
 in your platform-specific copy of the manual page).</para>

</section>

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

<para>You can use <function>EXT:EXPAND-FORM</function> to expand all
 the macros, &symbol-macro;s, etc, in a single form:
<programlisting>
 (expand-form '(macrolet ((bar (x) `(print ,x)))
                 (macrolet ((baz (x) `(bar ,x)))
                   (symbol-macrolet ((z 3))
                     (baz z)))))
</programlisting>
returns two values:
<literal role="sexp">(locally (print 3))</literal> (the expansion) and
&t; (an indicator that some expansion has actually been done).</para>

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

</chapter>

<chapter id="platform">
   <title>Extensions-2: Platform specific Extensions</title>

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

<section id="screen"><title>Extensions-2.1. Random Screen Access</title>
<subtitle>Platform dependent: &unix;, &win32;
   platforms only.</subtitle>

<variablelist>
 <varlistentry><term><literal
    role="sexp">(<function>SCREEN:MAKE-WINDOW</function>)</literal></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><literal role="sexp"
    >(<function>SCREEN:WITH-WINDOW</function> . &body-r;)</literal></term>
  <listitem><simpara>binds
    <firstterm>&scr-win;<indexterm id="scr-win" significance="preferred">
      <primary id="scr-win-i"><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><literal role="sexp"
    >(<function>SCREEN:WINDOW-SIZE</function> &ws-r;)</literal></term>
  <listitem><simpara>returns the window's size, as two values:
   height (= y<subscript>max</subscript>+1) and width (=
   x<subscript>max</subscript>+1).
  </simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
 >(<function>SCREEN:WINDOW-CURSOR-POSITION</function> &ws-r;)</literal></term>
  <listitem><simpara>returns the position of the cursor in the window,
   as two values: line (&ge;0, &le;y<subscript>max</subscript>, 0 means
   top), column (&ge;0, &le;x<subscript>max</subscript>, 0 means left
   margin).</simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
    >(<function>SCREEN:SET-WINDOW-CURSOR-POSITION</function>
      &ws-r; <replaceable>line</replaceable>
      <replaceable>column</replaceable>)</literal></term>
  <listitem><simpara>sets the position of the cursor in the window.
  </simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
    >(<function>SCREEN:CLEAR-WINDOW</function> &ws-r;)</literal></term>
  <listitem><simpara>clears the window's contents and puts the cursor
    in the upper left corner.</simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
    >(<function>SCREEN:CLEAR-WINDOW-TO-EOT</function> &ws-r;)</literal></term>
  <listitem><simpara>clears the window's contents from the cursor
    position to the end of window.</simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
    >(<function>SCREEN:CLEAR-WINDOW-TO-EOL</function> &ws-r;)</literal></term>
  <listitem><simpara>clears the window's contents from the cursor
    position to the end of line.</simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
     >(<function>SCREEN:DELETE-WINDOW-LINE</function> &ws-r;)</literal></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><literal role="sexp"
    >(<function>SCREEN:INSERT-WINDOW-LINE</function> &ws-r;)</literal></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><literal role="sexp"
    >(<function>SCREEN:HIGHLIGHT-ON</function> &ws-r;)</literal></term>
  <listitem><simpara>switches highlighted output on.
 </simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
    >(<function>SCREEN:HIGHLIGHT-OFF</function> &ws-r;)</literal></term>
  <listitem><simpara>switches highlighted output off.
 </simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
    >(<function>SCREEN:WINDOW-CURSOR-ON</function> &ws-r;)</literal></term>
  <listitem><simpara>makes the cursor visible, a cursor block in most
    implementations.</simpara></listitem></varlistentry>
 <varlistentry><term><literal role="sexp"
    >(<function>SCREEN:WINDOW-CURSOR-OFF</function> &ws-r;)</literal></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>Extensions-2.2. External Modules</title>
<subtitle>Platform dependent: &unix; and &win32; platforms 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 <filename>lisp.run</filename> 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; run-time.
  This does &not-e; mean that they will not work on &win32;.</para>
</note>

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

<para>&clisp; has a facility for adding external modules (written in
 &c-lang;, for example).  It is invoked through
 <command>clisp-link</command>.</para>

<para>A <firstterm>module<indexterm id="module" significance="preferred">
   <primary id="module-i">module</primary></indexterm></firstterm> is a
 piece of external code which defines extra Lisp objects, symbols and
 functions.  A module name 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>.
 The module name <quote>clisp</quote> is reserved.
 Normally a module name is derived from the corresponding file name.</para>

<para><command>clisp-link</command> needs a directory containing:
<itemizedlist>
  <listitem><simpara><filename>modules.d</filename></simpara></listitem>
  <listitem><simpara><filename>modules.c</filename></simpara></listitem>
  <listitem><simpara><filename>clisp.h</filename></simpara></listitem>
</itemizedlist>
<command>clisp-link</command> expects to find these files in a
subdirectory <filename>linkkit/</filename> of the current directory.
This can be overridden by the &env-var; <envar>CLISP_LINKKIT</envar>.</para>

<para><command>clisp-link</command> operates on &clisp; &linkset;s and
 on &modset;s.</para>

<formalpara id="linkset"><title>&linkset;</title>
 <para>A <firstterm>&linkset;<indexterm id="linkseti" significance="preferred">
    <primary id="linkset-i">linking set</primary></indexterm></firstterm>
   is a directory containing:
<variablelist>
<varlistentry><term><filename>makevars</filename></term>
 <listitem><para>some &sh; commands, setting the variables
<variablelist><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
 </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><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><term>all the <filename>FILES</filename></term>
 <listitem><simpara>listed in <filename>makevars</filename>
</simpara></listitem></varlistentry>
<varlistentry><term><filename>lisp.run</filename></term>
 <listitem><simpara>the executable</simpara></listitem></varlistentry>
<varlistentry><term>&lispinit;</term>
 <listitem><simpara>the &mem-image;</simpara></listitem></varlistentry>
</variablelist></para></formalpara>

<para>To run a &clisp; contained in some &linkset;
 <filename>dir</filename>, call
 <command><replaceable>dir</replaceable>/lisp.run -M
 <replaceable>dir</replaceable>/lispinit.mem</command></para>

<formalpara id="modset"><title>&modset;</title>
 <para>A <firstterm>&modset;<indexterm id="modseti" significance="preferred">
    <primary id="modset-i">module set</primary></indexterm></firstterm>
   is a directory containing:
<variablelist>
<varlistentry><term><command>link.sh</command></term>
 <listitem><simpara>some &sh; commands, which prepare the directory
  before linking, and set the variables <envar>NEW_FILES</envar>,
  <envar>NEW_LIBS</envar>, <envar>NEW_MODULES</envar>, <envar>TO_LOAD</envar>
  and optionally <envar>TO_PRELOAD</envar></simpara></listitem></varlistentry>
<varlistentry><term>and any other files</term>
 <listitem><simpara>needed by <command>link.sh</command>
 </simpara></listitem></varlistentry>
</variablelist></para></formalpara>

<para>Note that in <command>link.sh</command> the &modset; directory
 is referred to as <varname>$modulename/</varname>.</para>

<variablelist>
<varlistentry><term><envar>NEW_FILES</envar></term>
 <listitem><simpara>the space-separated list of files that
  belong to the &modset; and will belong to every new &linkset;.
 </simpara></listitem></varlistentry>
<varlistentry><term><envar>NEW_LIBS</envar></term>
 <listitem><simpara>the space-separated list of files 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 derived
  from the file name.</simpara></listitem></varlistentry>
<varlistentry><term><envar>TO_LOAD</envar></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><term><envar>TO_PRELOAD</envar> (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 for defining Lisp packages 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"/>.</simpara></listitem></varlistentry>
</variablelist>

<para>The command <command>clisp-link create-module-set
 <replaceable>module-dir</replaceable>
 <replaceable>file1.c</replaceable> ...</command> creates a &modset;
 in <replaceable>module-dir</replaceable> which refers (via symbolic
 links) to <replaceable>file1.c</replaceable> etc.  The files are
 expected to be modules of their own.</para>

<para>The command <command>clisp-link add-module-set
 <replaceable>module-dir</replaceable>
 <replaceable>source-dir</replaceable>
 <replaceable>destination-dir</replaceable></command> combines a
 &linkset; in <replaceable>source-dir</replaceable> and a module in
 <replaceable>module-dir</replaceable> to a new &linkset;, in a
 directory <replaceable>destination-dir</replaceable> which is newly
 created.</para>

<para>The command <command>clisp-link run <replaceable>source-dir</replaceable>
 <replaceable>module-dir</replaceable> ...</command> runs the &linkset;
 in <replaceable>source-dir</replaceable>, with the module in
 <replaceable>module-dir</replaceable> loaded.  More than one module can
 be specified.  If &clisp; has been built with the configuration option
 <option>--with-dynamic-modules</option>, the loading will be performed
 through dynamic loading.  Otherwise - this is much slower - a temporary
 &linkset; will be created and deleted afterwards.  Note that dynamic
 loading does not work on all operating systems, and that
 <option>--with-dynamic-modules</option> precludes some efficiency
 optimizations which are enabled by default.</para>

</section>

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

<para>Function <literal role="sexp">(&modinfo; &optional-amp; &name-r;
  <replaceable>verbose</replaceable>)</literal> 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></section>

<section id="mod-dynload"><title>Function &mod-dynload;</title>
<subtitle>Platform dependent: some &unix; platforms only, compiled &with;
 compile-time flag <option>--with-dynamic-modules</option>.</subtitle>

<note><para>Note that dynamic loading does not work on all operating systems
(&dlopen; is required), and that <option>--with-dynamic-modules</option>
precludes some efficiency optimizations which are on by default.</para></note>

<para>Function <literal role="sexp">(&mod-dynload; &filename-r;
 ({&name-r;}+))</literal> loads a shared object file or library
 containing a number of named external &clisp; modules.
 This facility cannot be used to &dlopen; and access arbitrary shared
 libraries.</para>

<para>External modules for &clisp; are those which contain a
 <literal>module__&name-r;__subr_tab</literal>, 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
 <option>-fPIC</option> to the module's compilation options.
 Something like <command>cc -shared -o &name-r;.so &name-r;.o</command>
 may be needed to produce the shared object file.</para>

</section>

<section id="mod-set-example"><title>Example</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>

<orderedlist numeration="arabic">
<listitem><para>Create a new &modset;:

<programlisting>$ clisp-link create-module-set linux /<replaceable>somewhere</replaceable>/bindings/linux.c</programlisting>

 Modify the newly created <filename>linux/link.sh</filename> to add
 <option>-lm</option>; to the libraries: replace
<programlisting>NEW_LIBS="$file_list"</programlisting>
   with
<programlisting>NEW_LIBS="$file_list -lm"</programlisting>

   Modify the newly created <filename>linux/link.sh</filename> to load
   <filename>linux.fas</filename> before saving the &mem-image;:
   replace
<programlisting>TO_LOAD=''</programlisting>
   with
<programlisting>TO_LOAD='/<replaceable>somewhere</replaceable>/bindings/linux.fas'</programlisting></para></listitem>

<listitem><para>Compile <filename>linux.lisp</filename>, creating
  <filename>linux.c</filename>:

<programlisting>$ clisp -c /<replaceable>somewhere</replaceable>/bindings/linux.lisp</programlisting></para></listitem>

<listitem><para>Create a new &linkset;:
<programlisting>$ clisp-link add-module-set linux base base+linux</programlisting></para></listitem>

<listitem><para>Run and try it:

<programlisting>$ base+linux/lisp.run -M base+linux/lispinit.mem -x '(linux:stat "/tmp")'</programlisting></para></listitem>

</orderedlist>

</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 <filename>modprep.lisp</filename> in the &clisp;
 distribution and define lisp functions with the
 <function>DEFUN</function> macro:<programlisting>
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 <literal role="sexp">(MY-PACKAGE:MY-FUNCTION-NAME 'A 12 :FOO
 T)</literal> will return <literal role="sexp">(A 12 T 0
 MY-PACKAGE::SOME-SYMBOL #(:THIS :IS :A :VECTOR)
 #&lt;ADD-ON-SYSTEM-FUNCTION MY-PACKAGE:MY-FUNCTION-NAME&gt;)</literal>
(assuming you &export;ed <literal>MY-FUNCTION-NAME</literal> from
 <quote role="package">MY-PACKAGE</quote>).</para>

<para>Another useful macro is <function>DEFVAR</function> which lets
 you create a GC-visible object.</para>
<para>See <filename>modules/syscalls</filename> and other included
 modules for more examples and file <filename>modprep.lisp</filename>
 for full documentation.</para>
<warning><para>If you manipulate Lisp objects, you need to watch for
  <link linkend="gc-safety">GC-safety</link>.</para></warning>
</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
 <link linkend="make-pack">case-sensitive</link> and use
 <filename>exporting.lisp</filename> in the &clisp; distribution to
 make all &ffi-pac; forms export the symbols they define.
 See <filename>modules/netica</filename>
 and <filename>modules/bindings/*</filename> for examples.</para>
</section>

</section>

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

<para>The following modules come with the distribution of
&clisp;:</para>

<variablelist>
 <varlistentry><term>bindings</term>
  <listitem><para>Call the operating system functions from &clisp;.
    The following platforms are supported:
   <itemizedlist>
    <listitem><simpara>&linux;/&glibc;</simpara></listitem>
    <listitem><simpara>&win32;</simpara></listitem>
   </itemizedlist></para></listitem></varlistentry>
 <varlistentry><term>&clx;</term>
  <listitem><para>Call
    <ulink url="http://www.the-labs.com/X11/XLib-Manual/">Xlib</ulink>
    functions from &clisp;.  Two implementations are supplied:
   <itemizedlist>
    <listitem><simpara>mit-clx, from MIT
     <ulink url="ftp://ftp.x.org/R5contrib/CLX.R5.02.tar.Z"
            >ftp://ftp.x.org/R5contrib/CLX.R5.02.tar.Z</ulink>
     - the standard implementation</simpara></listitem>
    <listitem><simpara>new-clx, by &gilbert-baumann;
      - faster, with additional features, but not quite complete yet.
    </simpara></listitem>
 </itemizedlist></para></listitem></varlistentry>
 <varlistentry><term><link linkend="oracle">oracle</link></term>
  <listitem><simpara>Access
    <ulink url="http://www.oracle.com/">Oracle</ulink> from &clisp;;
    by &hin;.</simpara></listitem></varlistentry>
 <varlistentry><term><link linkend="fastcgi">fastcgi</link></term>
  <listitem><simpara>Access
    <ulink url="http://www.fastcgi.com/">FastCGI</ulink> from &clisp;;
    by &hin;.</simpara></listitem></varlistentry>
 <varlistentry><term><link linkend="netica">netica</link></term>
  <listitem><simpara>Work with Bayesian belief networks and influence
    diagrams using
    <ulink url="http://norsys.com/netica_c_api.htm">Netica</ulink>.
 </simpara></listitem></varlistentry>
 <varlistentry><term>postgresql</term>
  <listitem><simpara>Access
    <ulink url="http://www.PostgreSQL.org/">PostgreSQL</ulink> from &clisp;.
  </simpara></listitem></varlistentry>
 <varlistentry><term>queens</term>
  <listitem><simpara>Compute the number of solutions to the n-queens
    problem on a n*n checkboard (a toy example for the users to
    explore).</simpara></listitem></varlistentry>
 <varlistentry><term><link linkend="dir-key">dirkey</link></term>
  <listitem><simpara>Directory Access</simpara></listitem></varlistentry>
 <varlistentry><term><link linkend="berkeley-db">berkeley-db</link></term>
  <listitem><simpara>&sleepycat-berkeley-db;
    interface</simpara></listitem></varlistentry>
 <varlistentry><term><link linkend="regexp">regexp</link></term>
  <listitem><simpara>The <ulink url="regexp.html">POSIX Regular
   Expressions</ulink> matching, compiling, executing.
 </simpara></listitem></varlistentry>
 <varlistentry><term><link linkend="pcre">pcre</link></term>
  <listitem><simpara>The <ulink url="http://www.pcre.org/">Perl
     Compatible Regular Expressions</ulink> matching, compiling,
    executing.</simpara></listitem></varlistentry>
 <varlistentry><term><link linkend="syscalls">syscalls</link></term>
  <listitem><simpara>Use some system calls in a platform-independent way.
 </simpara></listitem></varlistentry>
 <varlistentry><term><ulink url="wildcard.html">wildcard</ulink></term>
  <listitem><simpara>Shell (&sh;) globbing</simpara></listitem></varlistentry>
</variablelist>

&netica;

&dirkey;

&berkeley-db;

&regexp;

&pcre;

&syscalls;

&oracle;

&fastcgi;

</section>

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

<!-- #ifdef DYNAMIC_FFI -->
<section id="dffi">
  <title>Extensions-2.3. The Foreign Function Call Facility</title>
<subtitle>Platform dependent: many &unix;, &win32; platforms
only.</subtitle>

<para>A foreign function description is written as a Lisp file, and when
 compiled it produces a &c-file; file which is then compiled by the
 &c-lang; compiler and may be linked together with
 <filename>lisp.a</filename>.</para>

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

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

<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 ANSI &c-lang;.</para>

<variablelist><title>special &ffi-pac; forms; &name-r; is any Lisp
   &symbol-t;; &cname-r; is a &string-t;.</title>
<varlistentry id="def-c-type">
 <term><literal role="sexp">(&def-c-type; &name-r; &ctype-r;)</literal></term>
 <listitem><simpara>This form makes &name-r; a shortcut for &ctype-r;.
   Note that &ctype-r; may already refer to name.
   Forward declarations of types are not possible, however.
</simpara></listitem></varlistentry>

<varlistentry id="def-c-var">
 <term><literal role="sexp">(&def-c-var; &name-r;
   {&option-r;}*)</literal></term>
 <listitem><simpara>This form defines a &foreign-variable;.
   &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><literal role="sexp">(&name-k;
      &cname-r;)</literal></term>
    <listitem><simpara>specifies the name as seen from &c-lang;, as a
      string.  If not specified, it is derived from the print name of
      the Lisp name.</simpara></listitem></varlistentry>
   <varlistentry><term><literal role="sexp">(&type-k;
      &ctype-r;)</literal></term>
    <listitem><simpara>specifies the variable's foreign type.
   </simpara></listitem></varlistentry>
   <varlistentry><term><literal role="sexp">(&ro-k;
      &boolean-t;)</literal></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><literal role="sexp">(:ALLOC
      &allocation;)</literal></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><literal role="sexp">(&library-k;
      &string-t;)</literal></term>
    <listitem><simpara>Specifies the (optional) dynamic library
      which contains the variable.
 </simpara></listitem></varlistentry></variablelist></listitem></varlistentry>

<varlistentry id="def-call-out"><term><literal role="sexp">(&def-call-out;
              &name-r; {&option-r;}*)</literal></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><literal role="sexp">(&name-k; &cname-r;)</literal></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><literal role="sexp">(&arguments-k;
   {(&arg-r; &ctype-r; [&param-mode; [&allocation;]])}*)</literal></term>
 <term><literal role="sexp">(&ret-type-k; &ctype-r;
   [&allocation;])</literal></term>
 <listitem><simpara>Argument list and return value, see
   <xref linkend="allocation"/> and <xref linkend="param-mode"/>.
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="sexp">(&lang-k; &lang-r;)</literal></term>
 <listitem><simpara>See <xref linkend="c-flavor"/>.
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="sexp">(:BUILT-IN
   &boolean-t;)</literal></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><literal role="sexp">(&library-k;
   &string-t;)</literal></term>
 <listitem><simpara>Specifies the (optional) dynamic library
  which contains the variable.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>

<varlistentry id="def-call-in"><term><literal role="sexp">(&def-call-in;
              &name-r; {&option-r;}*)</literal></term>
<listitem><simpara>This form defines 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><literal role="sexp">(&name-k; &cname-r;)</literal></term>
 <listitem><simpara>Any &c-lang; function call to the &c-lang; function
   &cname-r; is redirected to call the &cl; function
   <function>#'&name-r;</function>.</simpara></listitem></varlistentry>
<varlistentry><term><literal role="sexp">(&arguments-k;
   {(&arg-r; &ctype-r; [&param-mode; [&allocation;]])}*)</literal></term>
 <term><literal role="sexp">(&ret-type-k; &ctype-r;
   [&allocation;])</literal></term>
 <listitem><simpara>Argument list and return value, see
   <xref linkend="allocation"/> and <xref linkend="param-mode"/>.
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="sexp">(&lang-k; &lang-r;)</literal></term>
 <listitem><simpara>See <xref linkend="c-flavor"/>.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>

<varlistentry id="def-c-call-out"><term><literal role="sexp">(&def-c-call-out;
        &name-r; {&option-r;}*)</literal></term>
<listitem><simpara>This is equivalent to &def-call-out; with
   &lang-k; &stdc-k;.  <emphasis>deprecated</emphasis>.
   </simpara></listitem></varlistentry>

<varlistentry id="def-c-call-in"><term><literal role="sexp">(&def-c-call-in;
        &name-r; {&option-r;}*)</literal></term>
<listitem><simpara>This is equivalent to &def-call-in; with
   &lang-k; &stdc-k;.  <emphasis>deprecated</emphasis>.
   </simpara></listitem></varlistentry>

<varlistentry id="def-c-struct"><term><literal role="sexp">(&def-c-struct;
   &name-r; (&symbol-r; &ctype-r;)*)</literal></term>
 <listitem><para>This form defines &name-r; to be both a
  &structure-class; and a foreign &c-lang; type with the given slots.
  &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><constant>:EXTERNAL</constant></term>
    <listitem><simpara>means that this structure is defined in a
      &c-file; file that you include with, e.g.,
      <literal role="sexp">(&c-lines; "#include &lt;filename.h&gt;")</literal>.
  </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><literal role="sexp">(&def-c-enum;
   &name-r; {&symbol-r; | (&symbol-r; [&value-r;])}*)</literal></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
 <literal role="sexp">(<function>FFI:ENUM-FROM-VALUE</function> &name-r;
  &value-r;)</literal> and
 <literal role="sexp">(<function>FFI:ENUM-TO-VALUE</function> &name-r;
  &symbol-r;)</literal> 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><literal role="sexp">(&c-lines;
  <replaceable>format-string</replaceable> {&arg-r;}*)</literal></term>
 <listitem><simpara>This form outputs the string <literal
  role="sexp">(&format; &nil; <replaceable>format-string</replaceable>
    {&arg-r;}*)</literal> to the &c-lang; output file.
   This is a rarely needed low-level facility.
 </simpara></listitem></varlistentry>

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

<varlistentry id="deref"><term><literal role="sexp">(&deref;
                &cplace-r;)</literal></term>
<listitem><simpara>Dereference pointer: If
  &cplace-r; is of foreign type
  <literal role="type">(&c-ptr; &ctype-r;)</literal> or
  <literal role="type">(&c-ptr-null; &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><literal role="sexp">(&slot;
       &cplace-r; <replaceable>slot-name</replaceable>)</literal></term>
<listitem><simpara>Struct or union component: If &cplace-r; is of
  foreign type <literal role="type">(&c-struct; &class-r;
  ... (<replaceable>slot-name</replaceable> &ctype-r;) ...)</literal> or
  of type <literal role="type">(&c-union;
  ... (<replaceable>slot-name</replaceable> &ctype-r;) ...)</literal>,
  this will be of type &ctype-r;.
  </simpara></listitem></varlistentry>

<varlistentry id="cast"><term><literal role="sexp">(&cast;
           &cplace-r; &ctype-r;)</literal></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><literal role="sexp">(&offset;
           &cplace-r; &offset-r; &ctype-r;)</literal></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 <literal role="sexp">(&offset; &cplace-r; 0
  '(&c-array; <type>uint16</type> &k-r;))</literal>.
 </simpara></listitem></varlistentry>

<varlistentry id="c-var-addr"><term><literal role="sexp">(&c-var-addr;
           &cplace-r;)</literal></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><literal role="sexp">(&c-var-object;
   &cplace-r;)</literal></term>
 <listitem><simpara>Return the &foreign-variable; object underlying the
   &cplace-r;.  This is also an acceptable argument type to a &c-pointer;
   declaration.</simpara></listitem></varlistentry>

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

<varlistentry id="sizeof">
 <term><literal role="sexp">(&sizeof; &ctype-r;)</literal></term>
 <term><literal role="sexp">(&sizeof; &cplace-r;)</literal></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><literal role="sexp">(&bitsizeof; &ctype-r;)</literal></term>
 <term><literal role="sexp">(&bitsizeof; &cplace-r;)</literal></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="fa-null">
 <term><literal role="sexp">(&foreign-address-null; &f-ent;)</literal></term>
<listitem><simpara>This predicate returns &t; if the
  &f-ent; refers to the &c-NULL; address (and thus &f-ent; should
  probably not be passed to most foreign functions).
</simpara></listitem></varlistentry>

<varlistentry id="faddr-u">
 <term><literal role="sexp">(&foreign-address-unsigned;
   &f-ent;)</literal></term>
 <term><literal role="sexp">(&unsigned-foreign-address;
   &number-r;)</literal></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; or &foreign-function;.</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><literal role="sexp">(&foreign-address; &f-ent;)</literal></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 <literal role="sexp">(&ret-type-k;
    &c-pointer;)</literal> 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; or &foreign-function; 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="validp">
  <term><literal role="sexp">(&validp; &f-ent;)</literal></term>
  <term><literal role="sexp">(&setf; (&validp; &f-ent;)
    &value-r;)</literal></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 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
  <literal role="sexp">(&setf; &validp;)</literal>.
  You cannot resurrect a zombie, nor can you kill a non-foreign
  object.</simpara></listitem></varlistentry>

<varlistentry id="fptr">
 <term><literal role="sexp">(&foreign-pointer; &f-ent;)</literal></term>
 <term><literal role="sexp">(&setf; (&foreign-pointer; &f-ent;)
   &f-ptr;)</literal></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; or &foreign-function;.</simpara>
  <simpara><literal role="sexp">(&setf; &foreign-pointer;)</literal>
   changes the &foreign-pointer-t; associated with the Lisp object of
   type &foreign-address-t;, &foreign-variable; or &foreign-function; to
   that of the other entity.
   When &f-ptr; is &copy-k;, a &fresh; &foreign-pointer-t; is allocated.
   &f-ent; still points to the same object. This is particularly useful
   with <literal role="sexp">(&setf; &validp;)</literal>.
</simpara></listitem></varlistentry>

<varlistentry id="foreign-stack">
  <term><literal role="sexp">(&with-foreign-object; (&var-r; &ctype-r;
      [<replaceable>initarg</replaceable>]) &body-r;)</literal></term>
  <term><literal role="sexp">(&with-c-var; (&var-r; &ctype-r;
      [<replaceable>initarg</replaceable>]) &body-r;)</literal></term>
<listitem><simpara>These forms allocate space on the &c-lang; execution
  stack, bind respectively a &foreign-variable; 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 <literal role="sexp">(&sizeof;
  &ctype-r;)</literal> 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 place
  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="sexp">#()</literal>
  and <literal role="sexp">""</literal> are your friends for creating a
  pointer to the empty arrays:
<programlisting>(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>(with-c-var (fv `(c-array uint8 ,(length my-vector)) my-vector)
  (print fv))</programlisting>
 </para></listitem></varlistentry>

<varlistentry id="foreign-stack-string">
 <term><literal role="sexp">(&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;)</literal></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.
   <link linkend="charset-UTF-16"><constant>CHARSET:UTF-16</constant></link>
   or &utf-8;, circumventing the usual 1:1 limit imposed on
   &foreign-enc;.</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 &unsigned-byte-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-8;,
   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 &mblen;):
<programlisting>(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><literal role="sexp">(&parse-c-type; &ctype-r;)</literal></term>
 <term><literal role="sexp">(&deparse-c-type; &ctypei-r;)</literal></term>
 <listitem><simpara>Convert between the external (&list-t;) and internal
   (&vector-t;) &c-lang; type representations (used by &describe;).
</simpara></listitem></varlistentry>

<varlistentry id="foreign-heap">
 <term><literal role="sexp">(&allocate-shallow; &ctype-r;
   &key-amp; &count-k; &ro-k;)</literal></term>
 <term><literal role="sexp">(&allocate-deep; &ctype-r; &cont-r;
   &key-amp; &count-k; &ro-k;)</literal></term>
 <term><literal role="sexp">(&foreign-free; &f-ent;
   &key-amp; :FULL)</literal></term>
 <term><literal role="sexp">(&foreign-allocate; &ctypei-r;
   &key-amp; :INITIAL-CONTENTS &count-k; &ro-k;)</literal></term>
 <listitem><simpara>Macro &allocate-shallow; allocates
   <literal role="sexp">(&sizeof; &ctype-r;)</literal>
   bytes on the &c-lang; heap and zeroes them out (like &calloc;).
   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-c;).</simpara>
  <simpara>Returns a &foreign-variable; 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., <literal role="sexp">(&allocate-deep; '&c-string;
    "ABCDE")</literal> 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.  <literal role="sexp">(&allocate-shallow;
    '&c-string;)</literal> allocates room for a single pointer
   (probably 4 bytes).</simpara>
  <simpara><literal role="sexp">(&allocate-deep; '&character-t;
    "ABCDEF" :count 10)</literal> 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;, recursively frees
   the whole complex stucture pointed to by this variable.</simpara>
  <simpara>If given a &foreign-function; 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 <literal role="sexp">(&setf; &validp;)</literal> 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)
   signals an &error-t;. 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><literal role="sexp">(&with-c-place; (&var-r; &f-ent;)
   &body-r;)</literal></term>
 <listitem><simpara>Create a &place; out of the given &foreign-variable;
  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>(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;)
   <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>

</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><type>int</type></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><type>int</type></entry><entry>&integer-t;</entry>
   <entry><type>int</type></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>&unsigned-byte-8;</entry>
   <entry><type>uint8</type></entry><entry><type>BYTE</type></entry></row>
<row><entry><type>sint8</type></entry><entry>&signed-byte-8;</entry>
   <entry><type>sint8</type></entry></row>
<row><entry><type>uint16</type></entry><entry>&unsigned-byte-16;</entry>
   <entry><type>uint16</type></entry>
   <entry><type>SHORT CARDINAL</type></entry></row>
<row><entry><type>sint16</type></entry><entry>&signed-byte-16;</entry>
   <entry><type>sint16</type></entry>
   <entry><type>SHORT INTEGER</type></entry></row>
<row><entry><type>uint32</type></entry><entry>&unsigned-byte-32;</entry>
   <entry><type>uint32</type></entry><entry><type>CARDINAL</type></entry></row>
<row><entry><type>sint32</type></entry><entry>&signed-byte-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 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; (<replaceable>ident&sub-1;</replaceable>
   <replaceable>c-type&sub-1;</replaceable>) ...
  (<replaceable>ident&sub-n;</replaceable>
   <replaceable>c-type&sub-n;</replaceable>))</literal></term>
 <listitem><simpara>This type is equivalent to what &c-lang; calls
 <type>struct { <replaceable>c-type&sub-1;</replaceable>
 <replaceable>ident&sub-1;</replaceable>; ...;
 <replaceable>c-type&sub-n;</replaceable>
 <replaceable>ident&sub-n;</replaceable>; }</type>.
 Its Lisp equivalent is: if &class-r; is &vector-t;, a
 &simple-vector-t;; if &class-r; is &list-t;, a
 <ulink url="&clhs;/Body/glo_p.html#proper_list">proper list</ulink>;
 if &class-r; is a symbol naming a structure or &clos; class, an
 instance of this class, with slots of names
 <replaceable>ident&sub-1;</replaceable>, ...,
 <replaceable>ident&sub-n;</replaceable>.</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;
  (<replaceable>ident&sub-1;</replaceable>
   <replaceable>c-type&sub-1;</replaceable>) ...
  (<replaceable>ident&sub-n;</replaceable>
   <replaceable>c-type&sub-n;</replaceable>))</literal></term>
 <listitem><simpara>This type is equivalent to what &c-lang; calls
  <type>union { <replaceable>c-type&sub-1;</replaceable>
  <replaceable>ident&sub-1;</replaceable>; ...;
  <replaceable>c-type&sub-n;</replaceable>
  <replaceable>ident&sub-n;</replaceable>;
  }</type>.
  Conversion to and from Lisp assumes that a value is to be viewed as
  being of <replaceable>c-type&sub-1;</replaceable>.
 </simpara></listitem></varlistentry>

<varlistentry id="c-array"><term><literal role="type">(&c-array;
   &ctype-r; <replaceable>dim&sub-1;</replaceable>)</literal></term>
   <term><literal role="type">(&c-array;
   &ctype-r; (<replaceable>dim&sub-1;</replaceable> ...
   <replaceable>dim&sub-n;</replaceable>))</literal></term>
 <listitem><simpara>This type is equivalent to what &c-lang; calls
  <type>&ctype-r; [<replaceable>dim&sub-1;</replaceable>]
  ... [<replaceable>dim&sub-n;</replaceable>]</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 superfluous 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 <literal
  role="sexp">(<replaceable>r-c-type</replaceable> (*)
  (<replaceable>a-c-type&sub-1;</replaceable>, ...))</literal>.
  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 UNICODE -->
<para>&foreign-enc; governs conversion for any &ctype-r; involving
 &c-string; or &character-t; (but not <type>char</type>).</para>
<!-- #endif -->

</section>

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

<para>&c-function;, &def-call-in;, &def-call-out; take &lang-k; argument.
The &lang-r; is either &c-k; (denotes K&amp;R &c-lang;) or &stdc-k;
(denotes ANSI &c-lang;) or &stdc-sc-k; (denotes ANSI &c-lang;
with the <emphasis>stdcall</emphasis> 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 ANSI &c-lang; compiler,
and possibly the calling convention.</para>

<para>The default language is set using the macro
 <function>FFI:DEFAULT-FOREIGN-LANGUAGE</function>.
If this macro has not been called in the current
 <ulink url="&clhs;/Body/glo_c.html#compilation_unit">compilation
unit</ulink> (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>Foreign variables 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.  Note that for a foreign variable &x-r; the form <literal
 role="sexp">(&eql; &x-r; &x-r;)</literal> is not necessarily true,
 since every time &x-r; is evaluated its foreign value is converted to a
 &fresh; Lisp value.  Foreign variables are defined using
 &def-c-var;.</para>

</section>

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

<para>A &foreign-variable; &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 "lvalue" in &c-lang; terminology.)
 The following operations are available on foreign places:
 &element;, &deref;, &slot;, &cast;, &offset;, &c-var-addr;,
 &c-var-object;, &typeof;, &sizeof;, &bitsizeof;.</para>

</section>

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

<para>Foreign functions are functions which are defined in the foreign
 language.  There are <emphasis>named foreign functions</emphasis>
 (imported via &def-call-out; or created via &def-call-in;) and
 <emphasis>anonymous foreign functions</emphasis>; they arise through
 conversion of function pointers.</para>

<para>A <emphasis>"call-out"</emphasis> function is a foreign function
 called from Lisp: control flow temporarily leaves Lisp.  A
 <emphasis>"call-in"</emphasis> function is a Lisp function called from
 the foreign language: control flow temporary enters Lisp.</para>

<para>The following forms define foreign functions: &def-call-in;,
 &def-call-out;, &def-c-call-in;, &def-c-call-out;.</para>

</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 freed 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. [Subject to
 change!]  The &malloc-free-k; policy provides the ability to pass
 arbitrarily nested structs containing pointers pointing to structs
 ... within a single conversion.</para>

<variablelist>
<varlistentry><term>For call-out functions:</term>
<listitem><variablelist>
 <varlistentry><term>For arguments passed from Lisp to &c-lang;:</term>
  <listitem><variablelist>
   <varlistentry><term>If &allocation; is &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>If &allocation; is &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>If &allocation; is &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.
     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>If &allocation; is &malloc-free-k;:</term>
    <listitem><simpara>Lisp calls &free; on it when done.
    </simpara></listitem></varlistentry>
   <varlistentry><term>If &allocation; is &none-k;:</term>
    <listitem><simpara>Lisp does nothing.
    </simpara></listitem></varlistentry></variablelist>
  </listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>For call-in functions:</term>
 <listitem><variablelist>
  <varlistentry><term>For arguments passed from &c-lang; to Lisp:</term>
   <listitem><variablelist>
    <varlistentry><term>If &allocation; is &malloc-free-k;:</term>
     <listitem><simpara>Lisp calls &free; on it when done.
     </simpara></listitem></varlistentry>
    <varlistentry><term>If &allocation; is &alloca-k; or &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>If &allocation; is &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>If &allocation; is &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.
     This is dangerous! and deprecated.
    </simpara></listitem></varlistentry></variablelist>
 </listitem></varlistentry></variablelist></listitem></varlistentry>
</variablelist>

<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 hppa and &win32;) have problems with this.
  The recommended workaround is to pass pointers; this is fully supported.
  See also this &clisp-list;
  <ulink url="http://article.gmane.org/gmane.lisp.clisp.devel/10089"
         >message</ulink>.</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.
  </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 multiple value.
  </simpara></listitem></varlistentry>
</variablelist>

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

<para>[Currently, only &in-k; is fully implemented.  &out-k; works only
 with &allocation; = &alloca-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>
struct foo {
    int a;
    struct foo * b[100];
};
</programlisting>

corresponds to

<programlisting>
(def-c-struct foo
  (a int)
  (b (c-array (c-ptr foo) 100)))
</programlisting></para>

<para>The element access

<programlisting>
struct foo f;
f.b[7].a
</programlisting>

corresponds to

<programlisting>
(declare (type foo f))
(foo-a (aref (foo-b f) 7)) or (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>
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>
(def-c-struct bar
  (x short)
  (y short)
  (a char)
  (b char) ; or (b character) if it represents a character, not a number
  (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))
or (incf (slot my_struct 'x))
(setq my_struct (let ((s my_struct)) (setf (slot-value s 'a) 5) s))
or (setf (slot my_struct 'a) 5)
(setq my_struct (slot-value my_struct 'n))
or (setq my_struct (deref (slot my_struct 'n)))
</programlisting></para></example>

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

<para>On ANSI &c-lang; systems, &stdlib-h; contains the declarations:

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

This translates to

<programlisting>
(def-c-struct (div_t :typedef)
  (quot int)
  (rem int))
(default-foreign-language :stdc)
(def-call-out div (:arguments (numer int) (denom int))
  (:return-type div_t))
</programlisting>

Sample call from within Lisp:

<programlisting>
(div 20 3)
<returnvalue>#S(DIV_T :QUOT 6 :REM 2)</returnvalue>
</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>
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; would
<link linkend="c-file-overwrite">overwrite</link>
<filename>cfun.c</filename>) whose contents is:

<programlisting>
(&defpackage; "TEST-C-CALL" (:use "LISP" "FFI"))
(&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
    (:arguments (i int)
                (s c-string)
                (r (c-ptr cfunr) :in :alloca)
                (a (c-ptr (c-array int 10)) :in :alloca))
  (:return-type (c-ptr cfunr)))
(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:

<programlisting>
$ clisp-link create-module-set cfun callcfun.c
$ cc -O -c cfun.c
$ cd cfun
$ ln -s ../cfun.o cfun.o
Add cfun.o to NEW_LIBS and NEW_FILES in link.sh.
$ cd ..
$ base/lisp.run -M base/lispinit.mem -c callcfun.lisp
$ clisp-link add-module-set cfun base base+cfun
$ base+cfun/lisp.run -M base+cfun/lispinit.mem -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;
$ rm -r base+cfun
</programlisting></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>
(:return-type (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></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 &qsort;, one can use the
 following interface code <filename>sort1.c</filename>.
 The main problem is to pass a variable-sized array.

<programlisting>
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>
(&defpackage; "FFI-TEST" (:use "LISP" "FFI"))
(&in-package; "FFI-TEST")
(eval-when (compile) (setq &ffi-out-fun; t))
(def-call-in lispsort_begin (:arguments (n int))
  (:return-type nil)
  (:language :stdc))
(def-c-var lispsort_function (:type c-pointer))
(defun lispsort_begin (n)
  (setf (cast lispsort_function
              `(c-function
                 (:arguments (v (c-ptr (c-array double-float ,n))))
                 (:return-type (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>
(eval-when (compile) (setq &ffi-out-fun; t))
(def-call-out sort10
  (:name "lispsort_double")
  (:language :stdc)
  (:arguments (n int)
              (array (c-ptr (c-array double-float 10)) :in-out)))
</programlisting>

Now try

<programlisting>
$ clisp-link create-module-set sort sort2.c sorttest.c
$ cc -O -c sort1.c
$ cd sort
$ ln -s ../sort1.o sort1.o
</programlisting>

Add <filename>sort1.o</filename> to <envar>NEW_LIBS</envar>
and <envar>NEW_FILES</envar> in <filename>link.sh</filename>.
Create a file <filename>package.lisp</filename> containing the
form <literal role="sexp">(&defpackage; "FFI-TEST" (:use "LISP"
"FFI"))</literal> and add <filename>package.lisp</filename>
to <envar>TO_PRELOAD</envar> in <filename>link.sh</filename>.
Proceed:

<programlisting>
$ cd ..
$ base/lisp.run -M base/lispinit.mem -c sort2.lisp sorttest.lisp
$ clisp-link add-module-set sort base base+sort
$ base+sort/lisp.run -M base+sort/lispinit.mem -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)
$ rm -r base+sort
</programlisting></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>
typedef int (*LispFunc)(int parameter);
int CallInFunc(LispFunc f) {
  return f(5)+11;
}
</programlisting>
  and call it from Lisp:
  <programlisting>
(ffi:def-call-out callout
  (:name "CallInFunc")
  (:library "lispdll.dll")
  (:arguments (function-arg
               (ffi:c-function (:arguments (number ffi:int))
                               (:return-type ffi:int) (:language :stdc))))
  (:return-type ffi:int)
  (:language :stdc))
(defun f (x) (* x 2))
<returnvalue>F</returnvalue>
(callout #'f)
<returnvalue>21</returnvalue>
</programlisting></para></example>

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

<para><funcsynopsis id="gethostname-synopsis"><funcprototype>
   <funcdef><type>int</type> <function>gethostname</function></funcdef>
   <paramdef><type>char*</type> <parameter>name</parameter></paramdef>
   <paramdef><type>size_t</type> <parameter>namelen</parameter></paramdef>
</funcprototype></funcsynopsis>
 follows a typical pattern of &c-lang; "out"-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;.
 Additionaly, one must tell the function the size of the buffer.
 Here <replaceable>namelen</replaceable> 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
 <replaceable>namelen</replaceable> 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.</para>

<programlisting>
(&def-c-call-out; gethostname
  (:arguments (name (&c-ptr; (&c-array-max; ffi:char 256))
		    &out-k; &alloca-k;)
	      (len ffi:int))
  (:return-type ffi:int))

(defun myhostname ()
  (multiple-value-bind (success name)
      ;; &out-k; and &in-out-k; parameters are returned as &mul-val;
      (gethostname 256)
    (if (zerop success) name
	(error ...)))) ;; &strerror;(&errno;)

(defvar hostname (myhostname))
</programlisting>
</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>
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->out = ptr->out + ptr->x + ptr->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>
(&use-package; "FFI")

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

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

(&def-c-var; my-c-var (:name "my_struct")
  (:library "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>
(&c-var-addr; my-c-var)
<returnvalue>#&lt;FOREIGN-ADDRESS #x282935D8&gt;</returnvalue>
(get-own-c-float (&c-var-addr; my-c-var))
<returnvalue>30.5d0</returnvalue>
(get-own-c-float (&c-var-addr; my-c-var))
<returnvalue>61.0d0</returnvalue>
(get-own-c-float (&c-var-addr; my-c-var))
<returnvalue>91.5d0</returnvalue>
(get-own-c-float (&c-var-addr; my-c-var))
<returnvalue>122.0d0</returnvalue>
</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 &clisp-list; messages:
 <itemizedlist>
  <listitem><simpara><ulink url="http://article.gmane.org/gmane.lisp.clisp.general/7278">"variable size values"</ulink></simpara></listitem>
  <listitem><simpara><ulink url="http://article.gmane.org/gmane.lisp.clisp.general/6626">"variable length arrays"</ulink></simpara></listitem>
 </itemizedlist>
</para>
</section>
</section>

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


<!-- #ifdef HAVE_AFFI -->

<section id="affi">
  <title>Extensions-2.4. The Amiga Foreign Function Call Facility</title>
<subtitle>Platform dependent: no platform supports this currently.</subtitle>

<formalpara><title>Another Foreign Function Interface</title>
<para>All symbols relating to the simple foreign function interface are
 exported from the package &affi-pac;. To use them,
 <literal role="sexp">(&use-package; "AFFI")</literal>.</para>
</formalpara>

<section id="affi-design"><title>Design issues</title>

<para>&affi-pac; was designed to be small in size but powerful enough to
use most library functions.  Lisp files may be compiled to &fasl-file;
files without the need to load function definition files at run-time and
without external &c-lang; or linker support.
&mem-image;s can be created, provided that the function libraries are
opened at run-time.</para>

<para>Therefore, &affi-pac; supports only primitive &c-lang; types
(integers 8, 16 and 32 bits wide, signed or unsigned, pointers) and
defines no new types or classes.  Foreign functions are not first-class
objects (you can define a &lambda; yourself), name spaces are
separate.</para>

<para>The &affi-pac; does no tracking of resources.  Use &finalize;.</para>

</section>

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

<para>These are the &affi-pac; forms:</para>

<para><literal role="sexp">(declare-library-base
 <replaceable>keyword-base</replaceable> &lib-name;)</literal></para>

<para><literal role="sexp">(require-library-functions &lib-name;
 [(:import {<replaceable>string-name</replaceable>}*)])</literal></para>

<para><literal role="sexp">(open-library
 <replaceable>base-symbol</replaceable>)</literal></para>

<para><literal role="sexp">(close-library
 <replaceable>base-symbol</replaceable>)</literal></para>

<para><literal role="sexp">(with-open-library
 (<replaceable>base-symbol</replaceable> |
 &lib-name;) {&form-r;}*)</literal></para>

<para><literal role="sexp">(defflibfun
 <replaceable>function-name</replaceable>
 <replaceable>base-symbol</replaceable>
 &offset-r; <replaceable>mask</replaceable>
 <replaceable>result-type</replaceable>
 {<replaceable>argument-type</replaceable>}*)</literal></para>

<para><literal role="sexp">(declare-library-function
 <replaceable>function-name</replaceable>
 &lib-name; {&option-r;}*)</literal></para>

<para><literal role="sexp">(flibcall <replaceable>function-name</replaceable>
 {&arg-r;}*)</literal></para>

<para><literal role="sexp">(mlibcall <replaceable>function-name</replaceable>
 {&arg-r;}*)</literal></para>

<para><literal role="sexp">(mem-read &addr-r;
  <replaceable>result-type</replaceable> [&offset-r;])</literal></para>

<para><literal role="sexp">(mem-write &addr-r;
 &type-r; &value-r; [&offset-r;])</literal></para>

<para><literal role="sexp">(mem-write-vector &addr-r;
  <replaceable>vector</replaceable> [&offset-r;])</literal></para>

<para><literal role="sexp">(nzero-pointer-p &value-r;)</literal></para>

<para>Except for <function>with-open-library</function>,
<function>declare-library-function</function> and
<function>mlibcall</function>, all of the above are functions.</para>

<para>A library contains a collection of functions.  The library is
referred to by a symbol referred as library-base at the &affi-pac;
level.  This symbol is created in the package &affi-pac;.
The link between this symbol and the OS-level library name is
established by <function>declare-library-base</function>.  To avoid
multiple package conflicts, this and only this function requires the
symbol-name to be in the &kwd-pac; package. The function returns the
library-base.</para>

<para>A library may be opened by <function>open-library</function> and
 closed by <function>close-library</function>. An opened library must be
 closed. <function>with-open-library</function> is provided to
 automatically close the library for you, thus it is much safer to
 use.</para>

<para>A function is contained in a library.  Every function is referred
to by a symbol.  A function is defined through
<function>defflibfun</function> or
<function>declare-library-function</function> by giving the function
name, the library-base, an offset into the library, a mask (or &nil;)
for register-based library calls, the result type and all
parameter-types.  <function>require-library-functions</function> loads
the complete set of functions defined in a library file. Symbols are
created in the package &affi-pac; and imported into the current
package.</para>

<para><function>flibcall</function> and <function>mlibcall</function>
call library functions. <function>mlibcall</function> is a macro that
does a few checks at macroexpansion time and allows the compiler to
inline the call, not requiring the foreign function to be defined again
at load or execution time. The use of this macro is advertised wherever
possible.</para>

<para><function>mem-read</function> reads an arbitrary address (with
offset for structure references) and returns the given type.</para>

<para><function>mem-write</function> writes an arbitrary
address. <function>mem-write-vector</function> copies the content of a
Lisp &string-t; or &unsigned-byte-vec; into memory.</para>

<para><function>nzero-pointer-p</function> tests for
non-&c-NULL; pointers in all recognized representations
(&null-t;, &unsigned-byte-t; and &foreign-pointer-t;).</para>

</section>

<section id="affi-libs"><title>Foreign Libraries</title>

<para><function>declare-library-base</function> ought to be wrapped in an
<literal role="sexp">(&eval-when; (compile eval load) ...)</literal>
form and come before any function is referenced, because the library
base symbol must be known.</para>

<para><function>open-library</function> tries to open the library
referenced by the base symbol.  Therefore it must have been preceded
with <function>declare-library-base</function>.  The call returns &nil;
on failure. <function>open-library</function> calls nest.  Every
successful call must be matched by <function>close-library</function>.
<function>with-open-library</function> does this for you and also allows
you to specify the library by name, provided that its base has been
declared.  It is recommended to use this macro and to reference the
library by name.</para>

<para>&clisp; will not close libraries for you at program exit.  [A
previous version did so but now &affi-pac; is a module and there are no
module exit functions.]  Programmers, watch
<function>AFFI::*LIBRARIES-ALIST*</function>.</para>

</section>

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

<para>The following foreign &c-lang; types are used in &affi-pac;.
They are &not-e; regular &cl; types or &clos; classes.
<informaltable id="affi-types-tab" frame="all">
 <tgroup cols="5" colsep="1" rowsep="1" align="center">
 <thead><row><entry>&affi-pac; name</entry><entry>Lisp equivalent</entry>
 <entry>&c-lang; equivalent</entry><entry>Comment</entry></row></thead><tbody>
<row><entry>&nil;</entry><entry>&nil;</entry><entry><type>void</type></entry>
  <entry>as a result type for functions only</entry></row>
<row><entry><type>4</type></entry><entry>&unsigned-byte-32;</entry>
  <entry><type>unsigned long</type></entry><entry/></row>
<row><entry><type>2</type></entry><entry>&unsigned-byte-16;</entry>
  <entry><type>unsigned short</type></entry><entry/></row>
<row><entry><type>1</type></entry><entry>&unsigned-byte-8;</entry>
  <entry><type>unsigned char</type></entry><entry/></row>
<row><entry><type>-4</type></entry><entry>&signed-byte-32;</entry>
  <entry><type>long</type></entry><entry/></row>
<row><entry><type>-2</type></entry><entry>&signed-byte-16;</entry>
  <entry><type>short</type></entry><entry/></row>
<row><entry><type>-1</type></entry><entry>&signed-byte-8;</entry>
  <entry><type>signed char</type></entry><entry/></row>
<row><entry><type>0</type></entry><entry>&boolean-t;</entry>
  <entry><type>BOOL</type></entry>
  <entry>as a result type for functions only</entry></row>
<row><entry><type>*</type></entry><entry>opaque</entry>
  <entry><type>void*</type></entry><entry/></row>
<row><entry>&external-k;</entry><entry>opaque</entry>
  <entry><type>void*</type></entry><entry/></row>
<row><entry>&string-t;</entry>
  <entry>&string-t; or &vector-t;</entry>
  <entry><type>char*</type></entry><entry/></row>
<row><entry>&io-k;</entry>
  <entry>&string-t; or &vector-t;</entry>
  <entry><type>char*</type></entry><entry/></row>
</tbody></tgroup></informaltable></para>

<para>Objects of type &string-t; are copied and passed
&c-NULL;-terminated on the execution stack.  On return, a Lisp string is
allocated and filled from the address returned (unless &c-NULL;).
Functions with &io-k; parameters are passed the address of the Lisp
string or unsigned byte vector. These are not &c-NULL;-terminated!
This is useful for functions like like &read-c; which
do not need an array at a constant address longer than the dynamic
extent of the call (it is dangerous to define callback functions with
&io-k; (or &string-t;) type parameters).
Arguments of type &integer-t; and &foreign-pointer-t; are always
acceptable where a &string-t; or &io-k; type is specified.</para>

<!-- #ifdef UNICODE -->
<para>See also &foreign-enc;.</para>
<!-- #endif -->

<para>To meet the design goals, predefined types and objects were
used. As such, pointers were represented as integers. Now that there is
the &foreign-pointer-t; type, both representations may be used on input.
The pointer type should be therefore considered as opaque.
Use <function>nzero-pointer-p</function> for &c-NULL; tests.</para>

</section>

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

<para>Foreign Functions are declared either through
<function>defflibfun</function> or
<function>declare-library-function</function>.  The former is closer to
the low-level implementation of the interface, the latter is closer to
the other &ffi-pac;.</para>

<para><function>defflibfun</function> requires the library base symbol
and register mask to be specified,
<function>declare-library-function</function> requires the library name
and computes the mask from the declaration of the arguments.</para>

<para>The value of mask is implementation-dependent.</para>

<para>The &affi-pac; type &zero; is only acceptable as a
function result type and yields either &t; or &nil;. The difference
between <function>*</function> and &external-k; is the following:
<function>*</function> uses integers, &external-k; uses
&foreign-pointer-t; as function result-type (except from &nil; for a
&c-NULL; pointer) and refuses objects of type &string-t; or
&unsigned-byte-vec; as input.  Thus &external-k; provides some security
on the input and the ability to use &finalize; for resource-tracking on
the output side.</para>

<para><literal role="sexp">(declare-library-function &name-r;
 &lib-name; {&option-r;}*)</literal>

<variablelist>
 <varlistentry><term>&option-r; ::==</term>
 <listitem><informaltable id="affi-dec-lib-fun-opt-bnf" frame="all" role="bnf">
  <tgroup cols="2" colsep="1" rowsep="1" align="left"><tbody>
  <row><entry/><entry><literal role="sexp">(:offset
    <replaceable>library-offset</replaceable>)</literal></entry></row>
  <row><entry>|</entry><entry><literal role="sexp">(&arguments-k;
    {(&arg-r; <replaceable>&affi-pac;-type</replaceable>
      <replaceable>register</replaceable>)}*)</literal></entry></row>
  <row><entry>|</entry><entry><literal role="sexp">(:return-type
    <replaceable>&affi-pac;-type</replaceable>)</literal></entry></row>
</tbody></tgroup></informaltable></listitem></varlistentry>
<varlistentry><term><replaceable>register</replaceable> ::==</term>
 <listitem><simpara><constant>:d0</constant> | <constant>:d1</constant>
 | ... | <constant>:d7</constant> | <constant>:a0</constant> | ... |
 <constant>:a6</constant></simpara></listitem></varlistentry></variablelist>

declares a named library function for further reference through
<function>flibcall</function> and <function>mlibcall</function>.</para>

<para><function>mlibcall</function> should be the preferred way of
calling foreign functions (when they are known at compile-time) as
macroexpansion-time checks may be performed and the call can be sort of
inlined.</para>

</section>

<section id="affi-memory-access"><title>Memory access</title>

<para><literal role="sexp">(affi:mem-read &addr-r; &type-r;
  &offset-r;)</literal> can read 8, 16 and 32 bit
signed or unsigned integers (&affi-pac; types <type>-4</type>,
<type>-2</type>, <type>-1</type>, <type>1</type>, <type>2</type>,
<type>4</type>), a pointer (<type>*</type>), a &c-NULL;-terminated
string (<type>string</type>) or, if the type argument is of type
&string-t; or &unsigned-byte-vec;, it can fill this vector.
&external-k; is not an acceptable type as no object can be created by
using <function>affi:mem-read</function>.</para>

<para><literal role="sexp">(affi:mem-write &addr-r; &type-r; &value-r;
[&offset-r;])</literal> writes integers (&affi-pac;
type <type>-4</type>, <type>-2</type>, <type>-1</type>, <type>1</type>,
<type>2</type> and <type>4</type>) or pointer values (type
<type>*</type>), but not vectors to the specified memory address.</para>

<para><literal role="sexp">(affi:mem-write-vector &addr-r;
  <replaceable>vector</replaceable> [&offset-r;])</literal> can write
memory from the given vector (of type &string-t; or &unsigned-byte-vec;).
</para>

</section>

<section id="affi-func-def"><title>Function Definition Files</title>

<para><function>affi:require-library-functions</function> will &require; a
file of name derived from thelibrary name and with type
<filename>affi</filename>. It may be used to import all names into the
current package or only a given subset identified by string names, using
the <constant>:import</constant> keyword (recommended use).
Some definition files for standard Amiga libraries are provided.
See <xref linkend="affi-ex-1-predefined"/> below.</para>

<para>As <function>affi:require-library-functions</function> loads a
global file which you, the programmer, may have not defined, you may
consider declaring every function yourself to be certain what the return
and argument types are.
See <xref linkend="affi-ex-4-sample"/> below.</para>

<para>The file <filename>read-fd.lisp</filename> defines the function
<function>make-partial-fd-file</function> with which the provided
<filename>.affi</filename> files have been prepared from the original
Amiga FD files (located in the directory <filename>FD:</filename>).
They must still be edited as the function cannot know whether a function
accepts a <function>*</function>, &io-k;,
<function>string</function> or &external-k; argument and because files
in <filename>FD:</filename> only contain a register specification, not
the width of integer arguments (<literal>-4</literal>,
<literal>-2</literal>, <literal>-1</literal>, <literal>1</literal>,
<literal>2</literal>, or <literal>4</literal>).</para>

</section>

<section id="affi-hints"><title>Hints</title>

<para>By using appropriate &eval-when; forms for
<function>affi:declare-library-base</function> and
<function>affi:require-library-functions</function> and not using
<function>affi:flibcall</function>, it is possible to write code that
only loads library function definition files at compile-time.
See <xref linkend="affi-ex-1-predefined"/> below.</para>

<para>Do not rely on &finalize; to free resources for you, as &clisp;
does not call finalizers when it exits, use &unwind-protect;.</para>

</section>

<section id="affi-caveats"><title>Caveats</title>

<para>You can consider the library bases being symbols in need of being
imported from the package &affi-pac; originating from a brain-damage, causing
the usual symbol headaches when using foreign functions calls within
macros.  Luckily, even if the high-level interface (or its
implementation in <filename>affi1.lisp</filename>) were to change, the
low-level part (<filename>affi.d</filename>) should remain untouched as
all it knows are &integer-t;s and &foreign-pointer-t;s, no &symbol-t;s.
The difficulty is just to get the library base value at run-time.
Feel free to suggest enhancements to this facility!</para>

</section>

<section id="affi-examples"><title>Examples</title>
<subtitle>NB: These examples are somewhat specific to the Amiga.</subtitle>

<example id="affi-ex-1-predefined">
   <title>Using a predefined library function file</title>

<para><programlisting>
(&defpackage; "AFFI-TEST" (:use "LISP" "AFFI"))
(&in-package; "AFFI-TEST")

;; SysBase is the conventional name for exec.library
;; It is only enforced by the file loaded by REQUIRE-LIBRARY-FUNCTIONS
(eval-when (compile eval load)
  (declare-library-base :SysBase "exec.library")) ;keyword avoids name conflicts

;; using only MLIBCALL allows not to load definitions at load-time
(eval-when (compile eval)
  (require-library-functions "exec.library"
    :import '("FindTask")))

(with-open-library ("exec.library")
  (print (mlibcall FindTask 0)))
</programlisting>

This file can be used in interpreted and compiled mode.
Compiled, it will have inlined the library function calls.
</para></example>

<example id="affi-ex-2-flibcall"><title>Using flibcall</title>
<programlisting>
(&defpackage; "AFFI-TEST" (:use "LISP" "AFFI"))
(&in-package; "AFFI-TEST")

(eval-when (compile eval load)
  ;; keyword avoids name conflicts
  (declare-library-base :SysBase "exec.library"))

;; The load situation permits the use of flibcall
(eval-when (eval compile load)
  (require-library-functions "exec.library"))

(unless (open-library 'SysBase) (error "No library for SysBase"))
(flibcall (if t 'FindTask 'Debug) 0)
(close-library 'SysBase)
</programlisting></example>

<example id="affi-ex-3-dynamic">
   <title>Be fully dynamic, defining library bases ourselves</title>
<programlisting>
(&defpackage; "AFFI-TEST" (:use "LISP" "AFFI"))
(&in-package; "AFFI-TEST")

(eval-when (compile eval load)
  (defvar mylib (declare-library-base :foobase "foo.library")))
(eval-when (eval compile load)          ;eval allows mlibcall, load flibcall
  (defflibfun 'foo1 mylib -30 '#xA '* 'string)
  (defflibfun 'foo2 mylib -36 '#x21 0 * 4))

(defun foo (name)
  (when (open-library mylib)
    (list (mlibcall foo1 name) (flibcall 'foo2 name 123213))
    (close-library mylib)))
</programlisting></example>

<example id="affi-ex-4-sample"><title>Some sample function definitions</title>
<programlisting>
(defflibfun 'FindTask 'SysBase -294 #xA '* 'string)
(eval-library-function FindTask "exec.library"
  (:offset -294)
  (:return-type *)
  (:arguments
   (name   string   :A1)))
(declare-library-function NameFromLock "dos.library"
  (:offset -402)
  (:return-type 0)
  (:arguments
   (lock   4   :D1)
   (buffer :io :D2)
   (len    4   :D3)))

(eval-when (compile eval)
  (defconstant GVF_LOCAL_ONLY (ash 1 9))
  (defflibfun 'SetVar 'DosBase -900 #x5432 0 'string 'string -4 4))
(defun setvar (name value)
  (with-open-library (DosBase)
    ;; length of -1 means find length of &c-NULL;-terminated-string
    (mlibcall SetVar name value -1 GVF_LOCAL_ONLY)))
</programlisting></example>
</section>
</section>
<!-- #endif -->

<section id="socket"><title>Extensions-2.5. Socket Streams</title>
<subtitle>Platform dependent: &unix;, &win32; platforms only.</subtitle>
<!-- #ifdef SOCKET_STREAMS -->

<variablelist>
 <varlistentry id="sose"><term><literal role="sexp">(&sose; &optional-amp;
                 [<replaceable>port-or-socket</replaceable>])</literal></term>
  <listitem><simpara>This function creates a socket an binds a port to
    the socket.  The server exists to watch for client connect attempts.
    The optional argument is either a port (positive &fixnum-t;) or a
    &socket-stream; (from whose peer the connections will be made).
 </simpara></listitem></varlistentry>
 <varlistentry id="sose-close"><term><literal role="sexp">(&sose-close;
                 &sose-r;)</literal></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.
 </simpara></listitem></varlistentry>
 <varlistentry id="sose-hopo">
  <term><literal role="sexp">(&sose-host; &sose-r;)</literal></term>
  <term><literal role="sexp">(&sose-port; &sose-r;)</literal></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><literal role="sexp">(&so-wait;
    &sose-r; &timeout-opt;)</literal></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><literal role="sexp">(&so-accept;
    &sose-r; &key-amp; &eltype; &extfmt; &buffered;
    &timeout-k;)</literal></term>
  <listitem id="timeout-k"><simpara>Creates the server-side two-way
    &socket-stream; for the connection.
   Waits for an attempt to connect to the server for no more than
   &timeout-k; seconds (which may be a non-negative real number or a
   list <literal role="sexp">(sec usec)</literal> or a pair
   <literal role="sexp">(sec . usec)</literal>).
   &signal;s an &error-t; if no connection is made in that time.
  </simpara></listitem></varlistentry>
 <varlistentry id="so-connect"><term><literal role="sexp">(&so-connect;
    <replaceable>port</replaceable> &optional-amp; [&host-r;] &key-amp;
    &eltype; &extfmt; &buffered; &timeout-k;)</literal></term>
  <listitem><simpara>Attempts to create a client-side two-way
   &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><literal role="sexp">(&so-status;
                 <replaceable>socket-stream-or-list</replaceable>
                 &timeout-opt;)</literal></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>For the cognoscenti: this is the interface to &select;, so
   it will work for any &clisp; &stream-t; which is based on a
   &file-des;, e.g., &file-pipe-socket; and &kbd-in;.</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 <quote>status</quote> for a &socket-server; or a
    &socket-stream; to be &error-k; if any i/o operation will cause an
    error.</simpara>
   <simpara>Additionally, for a &socket-server;, we define
    <quote>status</quote> 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
    <quote>status</quote> in the given &direction-r; (one of &input-k;,
    &output-k;, and &io-k;) to be
    <variablelist id="so-status-values">
     <title>Possible status values for various directions:</title>
     <varlistentry><term>&input-k; status:</term>
      <listitem><variablelist>
        <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>
        <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><literal role="sexp">(&socket-stream;
       . &direction-r;)</literal></term>
     <listitem><simpara>Return the status in the specified direction
    </simpara></listitem></varlistentry>
    <varlistentry><term>a 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 &cons;ing up a &fresh; list, you can
    make the elements of <replaceable>socket-stream-or-list</replaceable>
    to be <literal role="sexp">(&sost-r; &direction-r; .
     &x-r;)</literal> or <literal role="sexp">(&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.</simpara>
 </listitem></varlistentry>
 <varlistentry id="sost-hopo">
  <term><literal role="sexp">(&sost-host; &sost-r;)</literal></term>
  <term><literal role="sexp">(&sost-port; &sost-r;)</literal></term>
  <listitem><simpara>These two functions return information about the
    &socket-stream;.</simpara></listitem></varlistentry>
 <varlistentry id="service-port"><term><literal role="sexp">(&service-port;
                 &optional-amp; <replaceable>service-name</replaceable>
                 (<replaceable>protocol</replaceable> "tcp"))</literal></term>
  <listitem><simpara>A convenience function for looking up a port given
   the service name.  It returns the servent struct as &mul-val;
   (name, list of aliases, port, protocol) for the given
   <replaceable>service-name</replaceable> and
   <replaceable>protocol</replaceable>, or all services as the list of
   <literal role="type">(&simple-vector-t; 4)</literal>
   if <replaceable>service-name</replaceable> is not given or is
   &default-k; or &nil;.</simpara></listitem></varlistentry>
 <varlistentry id="sost-peer"><term><literal role="sexp">(&sost-peer;
    &sost-r; [<replaceable>do-not-resolve-p</replaceable>])</literal></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</acronym> (Fully Qualified Domain Name).
   </simpara></listitem></varlistentry>
 <varlistentry id="sost-local"><term><literal role="sexp">(&sost-local;
    &sost-r; [<replaceable>do-not-resolve-p</replaceable>])</literal></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></listitem></varlistentry>
 <varlistentry id="sost-shut"><term><literal role="sexp">(&sost-shut;
    &sost-r; &direction-r;)</literal></term>
  <listitem><simpara>Some Internet protocols, such as &http;, provide for
   closing the connection in one &direction-r; using &shutdown;.
   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></listitem></varlistentry>
 <varlistentry id="so-opt"><term><literal role="sexp">(&so-opt;
    &sose-r; &rest-amp; {&option-r;}*)</literal></term>
  <listitem><simpara>Query and, optionally, set socket options using
   &getsockopt; 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., <literal role="sexp">(&so-opt; &sose-r;
   :SO-LINGER 1 :SO-RCVLOWAT)</literal> 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></listitem></varlistentry>
</variablelist>
<!-- #endif -->
</section>

<section id="quickstart">
   <title>Extensions-2.6. 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>

<variablelist>
 <varlistentry><term>&unix;</term>
  <listitem><simpara>&clisp; can act as a script interpreter.
  </simpara></listitem></varlistentry>
 <varlistentry><term>Desktop environments such as
   <ulink url="http://www.kde.org">KDE</ulink>,
   <ulink url="http://www.gnome.org">GNOME</ulink>, or Windows.</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>

<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 &cat;) into one file;
 the techniques then apply to that concatenated file.</para>

<variablelist>
<!-- #ifdef UNIX -->
<varlistentry id="quickstart-unix">
 <term>Platform dependent: &unix; platforms only.</term>
<listitem><para>On Unix, a text file (&fasl-file; or &lisp-file;) can be
 made executable by adding a first line of the form
 <programlisting>#!&interp-r; [&interp-args;]</programlisting>
 and using &chmod; to make the script executable.
 &clisp; can be used as a script interpreter under the following
 circumstances:</para>

<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>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,
 <option>-Msomewhere.mem</option> and <option>-C</option>) to &clisp;,
 separate them by hard spaces (ISO Latin-1 character 160) 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; at
 hard spaces and at normal spaces.</simpara></listitem>
</itemizedlist>

<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; (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 of strings, representing the arguments given to the Lisp
   script (i.e., <envar>$1</envar> in &sh; becomes <literal
   role="sexp">(&car; &args;)</literal> etc).</simpara></listitem>
  <listitem><simpara>&standard-input-var; and &standard-output-var; are
   bound, as usual, to the Unix standard input and output.
   &error-output-var; is bound to the Unix error output.</simpara></listitem>
  <listitem><simpara>Continuable errors will be turned to warnings
   (using &appease-cerrors;).</simpara></listitem>
  <listitem><simpara>Non-continuable errors and
   <keycombo>&ctrl;<keysym>C</keysym></keycombo> 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
  <olink targetdoc="man" targetptr="opt-load-comp"><option>-C</option></olink>
  to the &interp-args;.</simpara></listitem></itemizedlist>
 See also <olink targetdoc="man" targetptr="opt-exec-file">the manual</olink>.
</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>
#!/bin/sh
exec clisp &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 the standard output.  Another problem is that no user
input will be available.</para></formalpara>
</listitem></varlistentry>
<!-- #endif -->

<!-- #ifdef WIN32 -->
<varlistentry id="quickstart-win32">
 <term>Platform dependent: &win32; platforms only.</term>
<listitem><simpara>There are two different ways to make &clisp;
 "executables" for Windows platforms.</simpara>

<itemizedlist>
 <listitem><simpara>Associate the &mem-file; extension with
   <command>c:\clisp\lisp.exe -B c:\clisp -M %s</command>.
  </simpara></listitem>
 <listitem><simpara>Associate the &fasl-file; extension with
   <command>c:\clisp\lisp.exe -B c:\clisp -M c:\clisp\lispinit.mem
    -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\lisp.exe -B
    c:\clisp -M c:\clisp\lispinit.mem -i %s -x (main)</command>.
  </simpara></listitem>
</itemizedlist>

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

<para>Note that &clisp; is distributed with a file
 <filename>install.bat</filename>, which creates a file
 <filename>clisp.lnk</filename> on your desktop and also associates
 &fasl-file;, &lisp-file;, and &mem-file; files with &clisp;.</para>

</listitem></varlistentry>
<!-- #endif -->

<varlistentry id="quickstart-linux">
 <term>Platform dependent: &linux; platforms only.</term>

<listitem><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>root</literal>; you might want to put
 these lines into <filename>/etc/rc.d/rc.local</filename>):

<screen>
bash# echo ":CLISP:E::fas::/usr/local/bin/clisp:" &gt;&gt; /proc/sys/fs/binfmt_misc/register
bash# 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>
bash$ cat &lt;&lt; EOF &gt; hello.lisp
(print "hello, world!")
EOF
bash$ clisp -c hello.lisp

Compiling file hello.lisp ...

Compilation of file hello.lisp is finished.
0 errors, 0 warnings
bash$ chmod +x hello.fas
bash$ hello.fas

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

<para>Please read
 <filename>/usr/src/linux/Documentation/binfmt_misc.txt</filename> for
 details.</para>
</listitem></varlistentry>
</variablelist>

</section>

<section id="app-dev">
  <title>Extensions-2.7. Application delivery with &clisp;</title>

<para>Some ways of packaging &clisp; programs are discussed in the
 section <link linkend="quickstart">Quickstarting delivery with
 &clisp;</link>.</para>

<para>&clisp; is
 <ulink url="http://www.gnu.org/philosophy/free-sw.html">Free
  Software</ulink>, covered by the &gnu; &gpl;, with special
 terms governing the distribution of applications that run in &clisp;.
 The precise terms can be found in the <filename>COPYRIGHT</filename>
 file contained in the source and binary distributions of &clisp;.  Here
 is an informal clarification what these terms mean in practice.  Please
 refer to the said <filename>COPYRIGHT</filename> file when in
 doubt.</para>

<para>In many cases, &clisp; does not force an application to be covered
 by the &gnu; &gpl;. Nevertheless, we encourage you to release your software
 under an open source license. The benefits of such a license for
 your users are numerous, in particular they are free to modify the
 application when their needs/requirements change, and they are free to
 recompile the application when they upgrade their machine or operating
 system.</para>

<para>&clisp; extensions, i.e. programs which need to access
 non-portable &clisp; internal symbols (in the packages &sys-pac;,
 &clos-pac;, &ffi-pac;, ...), must be covered by &gnu; &gpl; as
 well.</para>

<para>Other programs running in &clisp; have to or need not to be placed
 under &gnu; &gpl;, depending on their distribution form:

<itemizedlist>
 <listitem><simpara>Programs distributed as Lisp source or &fasl-file;
   files can be distributed without restrictions coming from &clisp;.
 </simpara></listitem>
 <listitem><simpara>Programs distributed as &clisp; &mem-image;s can be
  distributed only if accompanied with the non-&clisp; &fasl-file; files
  which make up the &mem-image;, and a &make-file; for rebuilding the
  &mem-image;.</simpara></listitem>
 <listitem><simpara>If you need to distribute a modified &clisp;
  executable (for example, incorporating additional &module;s written
  in &c-lang;), you must distribute its full source under &gnu; &gpl;.
  If you are not satisfied with this, you can instead put the additional
  &module;s into a separate (non-&clisp;) program, with which your Lisp
  program will communicate via &socket-stream;s.</simpara></listitem>
</itemizedlist></para>

</section>

<section id="shell"><title>Extensions-2.8. Shell, Pipes and Printing</title>

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

<variablelist>
<!-- #ifdef UNIX -->
<varlistentry><term>Platform dependent: &unix; platforms only.</term>
 <listitem><simpara><literal role="sexp">(&exec; &program-r;
       <replaceable>arg&sub-1;</replaceable>
       <replaceable>arg&sub-2;</replaceable> ...)</literal>
   executes an external program.
   Its name is &program-r; (a full pathname).
   It is given the strings <replaceable>arg&sub-1;</replaceable>,
   <replaceable>arg&sub-2;</replaceable>, ... as arguments.
 </simpara></listitem></varlistentry>
<!-- #endif -->

<!-- #ifdef HAVE_SHELL -->
<varlistentry><term>Platform dependent: &unix;, &win32; platforms only.</term>
 <listitem><simpara><literal role="sexp">(&shell; [&command-r;])</literal>
   calls the operating system's shell, the value of the &env-var;
   <envar>SHELL</envar> on &unix; and <envar>COMSPEC</envar> on &win32;.
   <literal role="sexp">(&shell;)</literal> calls the shell
   for interactive use.
   <literal role="sexp">(&shell; &command-r;)</literal> calls the shell
   only for execution of the one given &command-r;.
 </simpara></listitem></varlistentry>
<!-- #endif -->

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

  <simpara><literal role="sexp">(&run-cmd; &command-r; &key-amp;
    &input-k; &output-k; &if-output-exists; &wait-k;)</literal>
   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><literal role="sexp">(&run-prog; &program-r; &key-amp;
    &arguments-k; &input-k; &output-k; &if-output-exists; &wait-k;)</literal>
   runs an external program.</simpara>

  <variablelist>
   <varlistentry><term>&command-r;</term>
    <listitem><simpara>the shell command.</simpara>
<!-- #ifdef UNIX -->
     <variablelist>
      <varlistentry><term>Platform dependent: &unix; platforms only.</term>
      <listitem><simpara>The shell the command is passed to is the value
       of the &env-var; <envar>SHELL</envar>, which normally is &sh;.
       The command should be a <quote>simple command</quote>;
       a <quote>command list</quote> should be enclosed in "{
       ... ; }" (for &sh;) or "( ... )" (for <filename>/bin/csh</filename>).
     </simpara></listitem></varlistentry></variablelist>
<!-- #endif -->
    </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 (strings) 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> (the standard input, default) or
     &stream-k; (a Lisp stream to be created) or
     a pathname (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> (the standard output, default) or
     &stream-k; (a Lisp stream to be created) or
     a pathname (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.,
    <literal role="sexp">(&run-prog; "dir" :indirectp &t;)</literal>
    will run the shell built-in command <command>DIR</command>.
    (&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;.
 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>Platform dependent: &unix;, &win32; platforms only.</term>
<listitem><variablelist>
 <varlistentry><term><literal role="sexp">(&mk-pipe-in;
    &command-r; &key-amp; &eltype; &extfmt; &buffered;)</literal></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><literal role="sexp">(&mk-pipe-out;
   &command-r; &key-amp; &eltype; &extfmt; &buffered;)</literal></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><literal role="sexp">(&mk-pipe-io;
   &command-r; &key-amp; &eltype; &extfmt; &buffered;)</literal></term>
<listitem><simpara>returns three values.
  The first value 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 will be the &in-s; and the &out-s; that
  make up the &bidi-s;, respectively.</simpara>
 <warning><simpara>Note that these three streams must be closed
   individually.</simpara></warning>
 <warning id="deadlock"><simpara>Note that 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 id="with-print-i">WITH-OUTPUT-TO-PRINTER<function></function>
 </primary></indexterm></firstterm>:
<programlisting>
(&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>Extensions-2.9. 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
<literal role="sexp">(&getenv; &optional-amp; &string-r;)</literal>,
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 <literal role="sexp">(&setf; (&getenv;
 &string-r;) <replaceable>new-value</replaceable>)</literal>.</para>
</section>

<section id="separate-io"><title>Extensions-2.10. Other</title>

<variablelist>
<!-- #ifdef UNIX -->
<varlistentry><term>Platform dependent: &unix; platforms only.</term>
<listitem><para>When running under the &X;, you can create
  a &bidi-s;, which uses a new dedicated xterm, using the function
  <firstterm>&mk-xterm-io;<indexterm id="mk-xterm" significance="preferred">
    <primary id="mk-xterm-i"><function>MAKE-XTERM-IO-STREAM</function>
  </primary></indexterm></firstterm>:
<programlisting>
  (&setq; &error-output-var;
    (&setq; &debug-io-var;
      (&mk-xterm-io;)))
</programlisting></para></listitem></varlistentry>
<!-- #endif -->
</variablelist>
</section>

</chapter>

</part>
