** Enchantments:
+ - Documentation is now included in main repository under toplevel
+ directory `doc'
+
- Update libffi to version 3.2.1
- Update asdf to version 3.1.4
- Dead code removals, untiabifying sources
- - Methods may now specialize on single-float and double-float
-
- Better quality of generated code (explicit casting when necessary)
** Issues fixed:
--- /dev/null
+ecl2.xml
+html/
+tmp/
--- /dev/null
+ GNU Free Documentation License
+ Version 1.1, March 2000
+
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+0. PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+written document "free" in the sense of freedom: to assure everyone
+the effective freedom to copy and redistribute it, with or without
+modifying it, either commercially or noncommercially. Secondarily,
+this License preserves for the author and publisher a way to get
+credit for their work, while not being considered responsible for
+modifications made by others.
+
+This License is a kind of "copyleft", which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+
+1. APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work that contains a
+notice placed by the copyright holder saying it can be distributed
+under the terms of this License. The "Document", below, refers to any
+such manual or work. Any member of the public is a licensee, and is
+addressed as "you".
+
+A "Modified Version" of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A "Secondary Section" is a named appendix or a front-matter section of
+the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall subject
+(or to related matters) and contains nothing that could fall directly
+within that overall subject. (For example, if the Document is in part a
+textbook of mathematics, a Secondary Section may not explain any
+mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The "Invariant Sections" are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License.
+
+The "Cover Texts" are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License.
+
+A "Transparent" copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, whose contents can be viewed and edited directly and
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup has been designed to thwart or discourage
+subsequent modification by readers is not Transparent. A copy that is
+not "Transparent" is called "Opaque".
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, LaTeX input format, SGML
+or XML using a publicly available DTD, and standard-conforming simple
+HTML designed for human modification. Opaque formats include
+PostScript, PDF, proprietary formats that can be read and edited only
+by proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the
+machine-generated HTML produced by some word processors for output
+purposes only.
+
+The "Title Page" means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, "Title Page" means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+
+2. VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+
+3. COPYING IN QUANTITY
+
+If you publish printed copies of the Document numbering more than 100,
+and the Document's license notice requires Cover Texts, you must enclose
+the copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a publicly-accessible computer-network location containing a complete
+Transparent copy of the Document, free of added material, which the
+general network-using public has access to download anonymously at no
+charge using public-standard network protocols. If you use the latter
+option, you must take reasonably prudent steps, when you begin
+distribution of Opaque copies in quantity, to ensure that this
+Transparent copy will remain thus accessible at the stated location
+until at least one year after the last time you distribute an Opaque
+copy (directly or through your agents or retailers) of that edition to
+the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+
+4. MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+A. Use in the Title Page (and on the covers, if any) a title distinct
+ from that of the Document, and from those of previous versions
+ (which should, if there were any, be listed in the History section
+ of the Document). You may use the same title as a previous version
+ if the original publisher of that version gives permission.
+B. List on the Title Page, as authors, one or more persons or entities
+ responsible for authorship of the modifications in the Modified
+ Version, together with at least five of the principal authors of the
+ Document (all of its principal authors, if it has less than five).
+C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+D. Preserve all the copyright notices of the Document.
+E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+F. Include, immediately after the copyright notices, a license notice
+ giving the public permission to use the Modified Version under the
+ terms of this License, in the form shown in the Addendum below.
+G. Preserve in that license notice the full lists of Invariant Sections
+ and required Cover Texts given in the Document's license notice.
+H. Include an unaltered copy of this License.
+I. Preserve the section entitled "History", and its title, and add to
+ it an item stating at least the title, year, new authors, and
+ publisher of the Modified Version as given on the Title Page. If
+ there is no section entitled "History" in the Document, create one
+ stating the title, year, authors, and publisher of the Document as
+ given on its Title Page, then add an item describing the Modified
+ Version as stated in the previous sentence.
+J. Preserve the network location, if any, given in the Document for
+ public access to a Transparent copy of the Document, and likewise
+ the network locations given in the Document for previous versions
+ it was based on. These may be placed in the "History" section.
+ You may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.
+K. In any section entitled "Acknowledgements" or "Dedications",
+ preserve the section's title, and preserve in the section all the
+ substance and tone of each of the contributor acknowledgements
+ and/or dedications given therein.
+L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section titles.
+M. Delete any section entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+N. Do not retitle any existing section as "Endorsements"
+ or to conflict in title with any Invariant Section.
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section entitled "Endorsements", provided it contains
+nothing but endorsements of your Modified Version by various
+parties--for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+
+5. COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections entitled "History"
+in the various original documents, forming one section entitled
+"History"; likewise combine any sections entitled "Acknowledgements",
+and any sections entitled "Dedications". You must delete all sections
+entitled "Endorsements."
+
+
+6. COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+
+7. AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, does not as a whole count as a Modified Version
+of the Document, provided no compilation copyright is claimed for the
+compilation. Such a compilation is called an "aggregate", and this
+License does not apply to the other self-contained works thus compiled
+with the Document, on account of their being thus compiled, if they
+are not themselves derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one quarter
+of the entire aggregate, the Document's Cover Texts may be placed on
+covers that surround only the Document within the aggregate.
+Otherwise they must appear on covers around the whole aggregate.
+
+
+8. TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License provided that you also include the
+original English version of this License. In case of a disagreement
+between the translation and the original English version of this
+License, the original English version will prevail.
+
+
+9. TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document is void, and will
+automatically terminate your rights under this License. However,
+parties who have received copies, or rights, from you under this
+License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+
+10. FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+http://www.gnu.org/copyleft/.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License "or any later version" applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+
--- /dev/null
+Instructions to edit/build this book
+====================================
+
+This is the recommended way to edit this manual. It is the one I found
+most convenient both under Linux and OS X.
+
+* Install the xmlto package. You can do it in almost any Linux machine
+ and also under OS X using the Fink packages.
+
+* Install Emacs (Linux) or Aquamacs (OS X).
+
+* Make sure you have the nxml-mode package. This is available in some
+ Linux distributions and comes for free with Aquamacs.
+
+* In the nxml-mode you should replace the Docbook schemas, which go
+ only up to version 4.2. These are the steps to do so:
+
+ - Go to http://www.docbook.org/schemas/4x.html
+
+ - Download the RELAX NG schema. It will suffice with docbook-rng-4.4.zip
+
+ - Go to the place where nxml stores its schema files. In Debian/Ubuntu
+ it is /usr/share/emacs/site-lisp/nxml-mode/schema, in Aquamacs it is
+ in /Applications/Aquamacs.app/Content/Resources/site-lisp/nxml-mode/schema.
+
+ - Make a backup copy of these schemas.
+
+ - Unzip the previous package directly on top of the directory mentioned before.
+
+After these steps, you should be able to edit the manual. To build it,
+ensure that the "xmlto" program is in some of the directories listed
+in the PATH environment variable and type "make" from the command
+line. This will build the HTML version.
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.arrays">
+ <title>Arrays</title>
+ <section xml:id="ansi.array-limits">
+ <title>Array limits</title>
+
+ <para>&ECL; arrays can have up to 64 dimensions. Common-Lisp constants
+ related to arrays have the following values in &ECL;.</para>
+ <informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Constant</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>array-rank-limit</entry>
+ <entry>64</entry>
+ </row>
+ <row>
+ <entry>array-dimension-limit</entry>
+ <entry>most-positive-fixnum</entry>
+ </row>
+ <row>
+ <entry>array-total-size-limit</entry>
+ <entry>array-dimension-limit</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </section>
+
+ <section xml:id="ansi.array-spec">
+ <title>Specializations</title>
+
+ <para>When the elements of an array are declared to have some precise type, such as a small or large integer, a character or a floating point number, &ECL; has means to store those elements in a more compact form, known as a <emphasis>specialized array</emphasis>. The list of types for which &ECL; specializes arrays is platform dependent, but is summarized in the following table, together with the C type which is used internally and the expected size.</para>
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Specialized type</entry>
+ <entry>Element C type</entry>
+ <entry>Size</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>bit</type></entry>
+ <entry>-</entry>
+ <entry>1 bit</entry>
+ </row>
+ <row>
+ <entry><type>character</type></entry>
+ <entry><type>unsigned char</type> or <type>uint32_t</type></entry>
+ <entry>Depends on character range</entry>
+ </row>
+ <row>
+ <entry><type>base-char</type></entry>
+ <entry><type>unsigned char</type></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><type>fixnum</type></entry>
+ <entry><type>cl_fixnum</type></entry>
+ <entry>Machine word (32 or 64 bits)</entry>
+ </row>
+ <row>
+ <entry><type>(signed-byte 8)</type></entry>
+ <entry><type>int8_t</type></entry>
+ <entry>8 bits</entry>
+ </row>
+ <row>
+ <entry><type>(unsigned-byte 8)</type></entry>
+ <entry><type>uint8_t</type></entry>
+ <entry>8 bits</entry>
+ </row>
+ <row>
+ <entry><type>(signed-byte 16)</type></entry>
+ <entry><type>int16_t</type></entry>
+ <entry>16 bits</entry>
+ </row>
+ <row>
+ <entry><type>(unsigned-byte 16)</type></entry>
+ <entry><type>uint16_t</type></entry>
+ <entry>16 bits</entry>
+ </row>
+ <row>
+ <entry><type>(signed-byte 32)</type></entry>
+ <entry><type>int32_t</type></entry>
+ <entry>32 bits</entry>
+ </row>
+ <row>
+ <entry><type>(unsigned-byte 32)</type></entry>
+ <entry><type>uint32_t</type></entry>
+ <entry>32 bits</entry>
+ </row>
+ <row>
+ <entry><type>(signed-byte 64)</type></entry>
+ <entry><type>int64_t</type></entry>
+ <entry>64 bits</entry>
+ </row>
+ <row>
+ <entry><type>(unsigned-byte 64)</type></entry>
+ <entry><type>uint64_t</type></entry>
+ <entry>64 bits</entry>
+ </row>
+ <row>
+ <entry><type>single-float</type> or <type>short-float</type></entry>
+ <entry><type>float</type></entry>
+ <entry>32-bits IEEE float</entry>
+ </row>
+ <row>
+ <entry><type>double-float</type></entry>
+ <entry><type>double</type></entry>
+ <entry>64-bits IEEE float</entry>
+ </row>
+ <row>
+ <entry><type>long-float</type></entry>
+ <entry><type>long double</type></entry>
+ <entry>Between 96 and 128 bits.</entry>
+ </row>
+ <row>
+ <entry><type>t</type></entry>
+ <entry><type>cl_object</type></entry>
+ <entry>Size of a pointer.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>Let us remark that some of these specialized types might not exist in your platform. This is detected using conditional reading and features (See <xref linkend="ansi.numbers.c-types"/>).</para>
+ </section>
+
+ <xi:include href="ref_c_arrays.xml" xpointer="ansi.arrays.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.characters">
+ <title>Characters</title>
+ <para>&ECL; is fully ANSI Common-Lisp compliant in all aspects of the character
+ data type, with the following peculiarities.</para>
+
+ <section xml:id="ansi.characeer.unicode">
+ <title>Unicode vs. POSIX locale</title>
+
+ <para>There are two ways of building &ECL;: with C or with Unicode character codes. These build modes are accessed using the <code>--disable-unicode</code> and <code>--enable-unicode</code> configuration options, the last one being the default.</para>
+
+ <para>When using C characters we are actually relying on the <type>char</type> type of the C language, using the C library functions for tasks such as character conversions, comparison, etc. In this case characters are typically 8 bit wide and the character order and collation are determines by the current POSIX or C locale. This is not very accurate, leaves out many languages and character encodings but it is sufficient for small applications that do not need multilingual support.</para>
+
+ <para>When no option is specified &ECL; builds with support for a larger character set, the Unicode 6.0 standard. This uses 24 bit large character codes, also known as <emphasis>codepoints</emphasis>, with a large database of character properties which include their nature (alphanumeric, numeric, etc), their case, their collation properties, whether they are standalone or composing characters, etc.</para>
+
+ <section xml:id="ansi.character-types">
+ <title>Character types</title>
+
+ <para>If compiled without Unicode support, &ECL; all characters are
+ implemented using 8-bit codes and the type <type>extended-char</type>
+ is empty. If compiled with Unicode support, characters are implemented
+ using 24 bits and the <type>extended-char</type> type covers characters above
+ code 255.</para>
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Type</entry>
+ <entry>With Unicode</entry>
+ <entry>Without Unicode</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>standard-char</type></entry>
+ <entry>#\Newline,32-126</entry>
+ <entry>#\Newline,32-126</entry>
+ </row>
+ <row>
+ <entry><type>base-char</type></entry>
+ <entry>0-255</entry>
+ <entry>0-255</entry>
+ </row>
+ <row>
+ <entry><type>extended-char</type></entry>
+ <entry>-</entry>
+ <entry>255-16777215</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </section>
+
+ <section xml:id="ansi.character-names">
+ <title>Character names</title>
+
+ <para>All characters have a name. For non-printing characters between 0 and 32, and for 127 we use the ordinary <acronym>ASCII</acronym> names. Characters above 127 are printed and read using hexadecimal Unicode notation, with a <literal>U</literal> followed by 24 bit hexadecimal number, as in <literal>U0126</literal>.</para>
+ <table xml:id="table.character-names">
+ <title>Examples of character names</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Character</entry>
+ <entry>Code</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row><entry><literal>#\Null</literal></entry><entry>0</entry></row>
+ <row><entry><literal>#\Ack</literal></entry><entry>1</entry></row>
+ <row><entry><literal>#\Bell</literal></entry><entry>7</entry></row>
+ <row><entry><literal>#\Backspace</literal></entry><entry>8</entry></row>
+ <row><entry><literal>#\Tab</literal></entry><entry>9</entry></row>
+ <row><entry><literal>#\Newline</literal></entry><entry>10</entry></row>
+ <row><entry><literal>#\Linefeed</literal></entry><entry>10</entry></row>
+ <row><entry><literal>#\Page</literal></entry><entry>12</entry></row>
+ <row><entry><literal>#\Esc</literal></entry><entry>27</entry></row>
+ <row><entry><literal>#\Escape</literal></entry><entry>27</entry></row>
+ <row><entry><literal>#\Space</literal></entry><entry>32</entry></row>
+ <row><entry><literal>#\Rubout</literal></entry><entry>127</entry></row>
+ <row><entry><literal>#\U0080</literal></entry><entry>128</entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>Note that <literal>#\Linefeed</literal> is synonymous with
+ <literal>#\Newline</literal> and thus is a member of
+ <type>standard-char</type>.</para>
+ </section>
+ </section>
+
+ <section>
+ <title><code>#\Newline</code> characters</title>
+
+ <para>Internally, &ECL; represents the <literal>#\Newline</literal> character by a single code. However, when using external formats, &ECL; may parse character pairs as a single <literal>#\Newline</literal>, and viceversa, use multiple characters to represent a single <literal>#\Newline</literal>. See <xref linkend="ansi.streams.formats"/>.</para>
+ </section>
+
+ <xi:include href="ref_c_characters.xml" xpointer="ansi.characters.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.conditions">
+ <title>Conditions</title>
+
+ <xi:include href="ref_c_conditions.xml" xpointer="ansi.conditions.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.conses">
+ <title>Conses</title>
+
+ <xi:include href="ref_c_conses.xml" xpointer="ansi.conses.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.data-and-control">
+ <title>Data and control flow</title>
+
+ <section xml:id="ansi.minimal-compilation">
+ <title>Minimal compilation</title>
+
+ <para>Former versions of &ECL;, as well as many other lisps, used linked
+ lists to represent code. Executing code thus meant traversing these lists
+ and performing code transformations, such as macro expansion, every time
+ that a statement was to be executed. The result was a slow and memory
+ hungry interpreter.</para>
+
+ <para>Beginning with version 0.3, &ECL; was shipped with a bytecodes
+ compiler and interpreter which circumvent the limitations of linked
+ lists. When you enter code at the lisp prompt, or when you load a source
+ file, &ECL; begins a process known as minimal compilation. Barely this
+ process consists on parsing each form, macroexpanding it and translating it
+ into an intermediate language made of
+ <emphasis>bytecodes</emphasis>.</para>
+
+ <para>The bytecodes compiler is implemented in
+ <filename>src/c/compiler.d</filename>. The main entry point is the lisp
+ function <function>si::make-lambda</function>, which takes a name for the
+ function and the body of the lambda lists, and produces a lisp object that
+ can be invoked. For instance,
+ <screen>> (defvar fun (si::make-lambda 'f '((x) (1+ x))))
+*FUN*
+> (funcall fun 2)
+3</screen></para>
+
+ <para>&ECL; can only execute bytecodes. When a list is passed to
+ <literal>EVAL</literal> it must be first compiled to bytecodes and, if the
+ process succeeds, the resulting bytecodes are passed to the
+ interpreter. Similarly, every time a function object is created, such as in
+ <function>DEFUN</function> or <function>DEFMACRO</function>, the compiler
+ processes the lambda form to produce a suitable bytecodes object.</para>
+
+ <para>The fact that &ECL; performs this eager compilation means that
+ changes on a macro are not immediately seen in code which was already
+ compiled. This has subtle implications. Take the following code:</para>
+ <screen>> (defmacro f (a b) `(+ ,a ,b))
+F
+> (defun g (x y) (f x y))
+G
+> (g 1 2)
+3
+> (defmacro f (a b) `(- ,a ,b))
+F
+> (g 1 2)
+3</screen>
+
+ <para>The last statement always outputs <literal>3</literal> while in former
+ implementations based on simple list traversal it would produce
+ <literal>-1</literal>.</para>
+ </section>
+
+ <section xml:id="ansi.functions">
+ <title>Function types</title>
+
+ <para>Functions in &ECL; can be of two types: they are either compiled to
+ bytecodes or they have been compiled to machine code using a lisp to C
+ translator and a C compiler. To the first category belong function loaded
+ from lisp source files or entered at the toplevel. To the second category
+ belong all functions in the &ECL; core environment and functions in files
+ processed by <function>compile</function> or
+ <function>compile-file</function>.</para>
+
+ <para>The output of <code>(symbol-function
+ <replaceable>fun</replaceable>)</code> is one of the following:
+ <itemizedlist>
+ <listitem><para>a function object denoting the definition of the function <literal>fun</literal>,</para></listitem>
+ <listitem><para>a list of the form <literal>(macro . function-object)</literal> when <literal>fun</literal> denotes a macro,</para></listitem>
+ <listitem><para>or simply <literal>'special</literal>, when <literal>fun</literal> denotes a special form, such as <symbol>block</symbol>, <symbol>if</symbol>, etc.</para></listitem>
+ </itemizedlist></para>
+
+ <para>&ECL; usually drops the source code of a function unless the global
+ variable <varname>si:*keep-definitions*</varname> was true when the
+ function was translated into bytecodes. Therefore, if you wish to use
+ <function>compile</function> and <function>disassemble</function> on
+ defined functions, you should issue <code>(setq si:*keep-definitions*
+ t)</code> at the beginning of your session.</para>
+
+ <para>In <xref linkend="table.function.constants"/> we list all
+ &CommonLisp; values related to the limits of functions.</para>
+
+ <table xml:id="table.function.constants">
+ <title>Function related constants</title>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry><constant>call-arguments-limit</constant></entry>
+ <entry>65536</entry>
+ </row>
+ <row>
+ <entry><constant>lambda-parameters-limit</constant></entry>
+ <entry>call-arguments-limit</entry>
+ </row>
+ <row>
+ <entry><constant>multiple-values-limit</constant></entry>
+ <entry>64</entry>
+ </row>
+ <row>
+ <entry><constant>lambda-list-keywords</constant></entry>
+ <entry><literal>(&optional; &rest; &key; &allow-other-keys; &aux;
+ &whole; &environment; &body;)</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section xml:id="ansi.calling-conventions">
+ <title>C Calling conventions</title>
+
+ <para>&ECL; is implemented using either a C or a C++ compiler. This is not a limiting factor, but imposes some constraints on how these languages are used to implement functions, multiple values, closures, etc. In particular, while C functions can be called with a variable number of arguments, there is no facility to check how many values were actually passed. This forces us to have two types of functions in &ECL;
+ <itemizedlist>
+ <listitem><para>Functions that take a fixed number of arguments have a simple C signature, with all arguments being properly declared, as in <code>cl_object cl_not(cl_object arg1)</code>.</para></listitem>
+ <listitem><para>Functions with a variable number of arguments, such as those acception <symbol>&optional;</symbol>, <symbol>&rest;</symbol> or <symbol>&key;</symbol> arguments, must take as first argument the number of remaining ones, as in <code>cl_object cl_list(cl_narg narg, ...)</code>. Here <replaceable>narg</replaceable> is the number of supplied arguments.</para></listitem>
+ </itemizedlist>
+ The previous conventions set some burden on the C programmer that calls &ECL;, for she must know the type of function that is being called and supply the right number of arguments. This burden disappears for Common Lisp programmers, though.</para>
+
+ <para>As an example let us assume that the user wants to invoke two functions which are part of the &ANSI; standard and thus are exported with a C name. The first example is <function>cl_cos</function>, which takes just one argument and has a signature <code>cl_object cl_cos(cl_object)</code>.</para>
+ <programlisting>
+#include <math.h>
+...
+cl_object angle = ecl_make_double_float(M_PI);
+cl_object c = cl_cos(angle);
+printf("\nThe cosine of PI is %g\n", ecl_double_float(c));
+</programlisting>
+
+ <para>The second example also involves some Mathematics, but now we are going to use the C function corresponding to <symbol>+</symbol>. As described in <link linkend="ansi.numbers.c-dict.ref">the C dictionary</link>, the C name for the plus operator is <function>cl_P</function> and has a signature <code>cl_object cl_P(cl_narg narg,...)</code>. Our example now reads as follows</para>
+ <programlisting>
+cl_object one = ecl_make_fixnum(1);
+cl_object two = cl_P(2, one, one);
+cl_object three = cl_P(2, one, one, one);
+printf("\n1 + 1 is %d\n", ecl_fixnum(two));
+printf("\n1 + 1 + 1 is %d\n", ecl_fixnum(three));
+</programlisting>
+
+ <para>Note that most Common Lisp functions will not have a C name. In this case one must use the symbol that names them to actually call the functions, using <function>cl_funcall</function> or <function>cl_apply</function>. The previous examples may thus be rewritten as follows</para>
+ <programlisting>
+/* Symbol + in package CL */
+cl_object plus = ecl_make_symbol("+","CL");
+cl_object one = ecl_make_fixnum(1);
+cl_object two = cl_funcall(3, plus, one, one);
+cl_object three = cl_funcall(4, plus, one, one, one);
+printf("\n1 + 1 is %d\n", ecl_fixnum(two));
+printf("\n1 + 1 + 1 is %d\n", ecl_fixnum(three));
+</programlisting>
+
+ <para>Another restriction of C and C++ is that functions can only take a limited number of arguments. In order to cope with this problem, &ECL; uses an internal stack to pass any argument above a hardcoded limit, <constant>ECL_C_CALL_ARGUMENTS_LIMIT</constant>, which is as of this writing 63. The use of this stack is transparently handled by the Common Lisp functions, such as <symbol>apply</symbol>, <symbol>funcall</symbol> and their C equivalents, and also by a set of macros, <link linkend="ref.ecl_va_arg"><function>cl_va_arg</function></link>, which can be used for coding functions that take an arbitrary name of arguments.</para>
+ </section>
+
+ <xi:include href="ref_c_data_flow.xml" xpointer="ansi.data-and-control.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.environment">
+ <title>Environment</title>
+
+ <section xml:id="ansi.environment.dict">
+ <title>Dictionary</title>
+
+ <refentry xml:id="ansi.environment.disassemble">
+ <refnamediv>
+ <refname><function>disassemble</function></refname>
+ <refpurpose>Display the assembly code of a function</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>disassemble</funcdef>
+ <paramdef><parameter>function-designator</parameter>*</paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>function-designator</replaceable></term>
+ <listitem><para>A symbol which is bound to a function in the global environment, or a lambda form
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Function</title>
+
+ <para>As specified in &ANSI; this function outputs the internal represention of a compiled function, or of a lambda form, as it would look after being compiled.</para>
+
+ <para>&ECL; only has a particular difference: it has two different compilers, one based on bytecodes and one based on the C language. The output will thus depend on the arguments and on which compiler is active at the moment in which this function is run.</para>
+ <itemizedlist>
+ <listitem><para>If the argument is a bytecompiled function, the output will be bytecodes.</para></listitem>
+ <listitem><para>If the argument is a lambda form, it will be processed by the active compiler and the appropriate output (bytecodes or C) will be shown.</para></listitem>
+ <listitem><para>If the argument is a C-compiled form, &ECL; will retrieve its original lambda form and process it with the currently active compiler.</para></listitem>
+ </itemizedlist>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="ansi.environment.trace">
+ <refnamediv>
+ <refname><function>trace</function></refname>
+ <refpurpose>Follow execution of functions</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>trace</funcdef>
+ <paramdef><parameter>function-name</parameter>*</paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>function-name</replaceable></term>
+ <listitem><para>
+ <synopsis>{<replaceable>symbol</replaceable> | (<replaceable>symbol</replaceable> [<replaceable>option</replaceable> <replaceable>form</replaceable>]*)}</synopsis>
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>symbol</replaceable></term>
+ <listitem><para>A symbol which is bound to a function in the global
+ environment. Not evaluated.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>option</replaceable></term>
+ <listitem><para>One of <symbol>:BREAK</symbol>,
+ <symbol>:BREAK-AFTER</symbol>, <symbol>:COND-BEFORE</symbol>,
+ <symbol>:COND-AFTER</symbol>, <symbol>:COND</symbol>,
+ <symbol>:PRINT</symbol>, <symbol>:PRINT-AFTER</symbol>,
+ <symbol>:STEP</symbol></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>form</replaceable></term>
+ <listitem><para>A lisp form evaluated in an special
+ environment.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem><para>List of symbols with traced functions.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Macro</title>
+
+ <para>Causes one or more functions to be traced. Each
+ <replaceable>function-name</replaceable> can be a symbol which is bound to
+ a function, or a list containing that symbol plus additional options. If
+ the function bound to that symbol is called, information about the
+ argumetns and output of this function will be printed. Trace options will
+ modify the amount of information and when it is printed.</para>
+
+ <para>Not that if the function is called from another function compiled in
+ the same file, tracing might not be enabled. If this is the case, to
+ enable tracing, recompile the caller with a <literal>notinline</literal>
+ declaration for the called function.</para>
+
+ <para><function>trace</function> returns a name list of those functions
+ that were traced by the call to trace. If no
+ <replaceable>function-name</replaceable> is given, <literal>trace</literal>
+ simply returns a name list of all the currently traced functions.</para>
+
+ <para>Trace options cause the normal printout to be suppressed, or cause
+ extra information to be printed. Each option is a pair of an option keyword
+ and a value form. If an already traced function is traced again, any new
+ options replace the old options and a warning might be printed. The lisp
+ <replaceable>form</replaceable> accompanying the option is evaluated in an
+ environment where <replaceable>sys::arglist</replaceable> is contains the
+ list of arguments to the function.</para>
+
+ <para>The following options are defined:</para>
+ <variablelist>
+ <varlistentry>
+ <term><symbol>:cond</symbol></term>
+ <term><symbol>:cond-before</symbol></term>
+ <term><symbol>:cond-after</symbol></term>
+ <listitem>
+ <para>If <symbol>:cond-before</symbol> is specified, then
+ <function>trace</function> does nothing unless
+ <replaceable>form</replaceable> evaluates to true at the time of the
+ call. <symbol>:cond-after</symbol> is similar, but suppresses the
+ initial printout, and is tested when the function returns.
+ <symbol>:cond</symbol> tries both before and after.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>:step</symbol></term>
+ <listitem>
+ <para>If <replaceable>form</replaceable> evaluates to true, the stepper
+ is entered.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>:break</symbol></term>
+ <term><symbol>:break-after</symbol></term>
+ <listitem>
+ <para>If specified, and <replaceable>form</replaceable> evaluates to
+ true, then the debugger is invoked at the start of the function or at
+ the end of the function according to the respective option.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>:print</symbol></term>
+ <term><symbol>:print-after</symbol></term>
+ <listitem>
+ <para>In addition to the usual printout, the result of evaluating
+ <replaceable>form</replaceable> is printed at the start of the function
+ or at the end of the function, depending on the option. Multiple print
+ options cause multiple values to be output, in the order in which they
+ were introduced.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ </refentry>
+ </section>
+
+ <xi:include href="ref_c_environment.xml" xpointer="ansi.environment.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.evaluation-and-compilation">
+ <title>Evaluation and compilation</title>
+
+ <section xml:id="ansi.declarations">
+ <title>Declarations</title>
+
+ <section xml:id="ansi.declarations.optimize">
+ <title><function>OPTIMIZE</function></title>
+
+ <para>The <function>OPTIMIZE</function> declaration includes three concepts:
+ <function>DEBUG</function>, <function>SPEED</function>,
+ <function>SAFETY</function> and <function>SPACE</function>. Each of these
+ declarations can take one of the integer values 0, 1, 2 and 3. According to
+ these values, the implementation may decide how to compie or interpret a
+ given lisp form.</para>
+
+ <para>&ECL; currently does not use all these declarations, but some of them
+ definitely affect the speed and behavior of compiled functions. For
+ instance, the <function>DEBUG</function> declaration, as shown in <xref
+ linkend="table.optimize.debug"/>, if the value of debugging is zero, the
+ function will not appear in the debugger and, if redefined, some functions
+ might not see the redefinition.</para>
+
+ <table xml:id="table.optimize.debug">
+ <title>Behavior for different levels of DEBUG</title>
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry>Behavior</entry>
+ <entry>0</entry>
+ <entry>1</entry>
+ <entry>2</entry>
+ <entry>3</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Compiled functions in the same source file are called
+ directly</entry>
+ <entry>Y</entry>
+ <entry>Y</entry>
+ <entry>N</entry>
+ <entry>N</entry>
+ </row>
+ <row>
+ <entry>Compiled function appears in debugger backtrace</entry>
+ <entry>N</entry>
+ <entry>N</entry>
+ <entry>Y</entry>
+ <entry>Y</entry>
+ </row>
+ <row>
+ <entry>All functions get a global entry, that is, SI:C-LOCAL is
+ ignored.</entry>
+ <entry>N</entry>
+ <entry>N</entry>
+ <entry>Y</entry>
+ <entry>Y</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>A bit more critical is the value of <function>SAFETY</function>
+ because as shown in Table <xref linkend="table.optimize.safety"/>, it may
+ affect the safety checks generated by the compiler. In particular, in some
+ circumstances the compiler may assume that the arguments to a function are
+ properly typed. For instance, if you compile with a low value of
+ <function>SAFETY</function>, and invoke <function>RPLACA</function>, the
+ consequences are unspecified.</para>
+
+ <table xml:id="table.optimize.safety">
+ <title>Behavior for different levels of SAFETY</title>
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry>Behavior</entry>
+ <entry>0</entry>
+ <entry>1</entry>
+ <entry>2</entry>
+ <entry>3</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>The compiler generates type checks for the arguments of a lambda
+ form, thus enforcing any type declaration written by the user.</entry>
+ <entry>N</entry>
+ <entry>Y</entry>
+ <entry>Y</entry>
+ <entry>Y</entry>
+ </row>
+ <row>
+ <entry>The value of an expression or a variable declared by the user is
+ assumed to be right.</entry>
+ <entry>Y</entry>
+ <entry>Y</entry>
+ <entry>N</entry>
+ <entry>N</entry>
+ </row>
+ <row>
+ <entry>We believe type declarations and type inference and, if the type
+ of a form is inferred to be right for a function, slot accessor, etc,
+ this may be inlined. Affects functions like CAR, CDR, etc</entry>
+ <entry>Y</entry>
+ <entry>Y</entry>
+ <entry>N</entry>
+ <entry>N</entry>
+ </row>
+ <row>
+ <entry>We believe types defined before compiling a file not change
+ before the compiled code is loaded.</entry>
+ <entry>Y</entry>
+ <entry>Y</entry>
+ <entry>N</entry>
+ <entry>N</entry>
+ </row>
+ <row>
+ <entry>Arguments in a lisp form are assumed to have the appropriate types
+ so that the form will not fail.</entry>
+ <entry>Y</entry>
+ <entry>N</entry>
+ <entry>N</entry>
+ <entry>N</entry>
+ </row>
+ <row>
+ <entry>The slots or fields in a lisp object are accessed directly
+ without type checks even if the type of the object could not be inferred
+ (see line above). Affects functions like PATHNAME-TYPE, CAR, REST,
+ etc.</entry>
+ <entry>Y</entry>
+ <entry>N</entry>
+ <entry>N</entry>
+ <entry>N</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </section>
+ </section>
+
+ <xi:include href="ref_c_evaluation.xml" xpointer="ansi.evaluation.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.filenames">
+ <title>Filenames</title>
+
+ <section xml:id="ansi.filenames.syntax">
+ <title>Syntax</title>
+ <para>A pathname in the file system of Common-Lisp consists of six
+ elements: host, device, directory, name, type and version. Pathnames are
+ read and printed using the <literal>#P</literal> reader macro followed by
+ the namestring. A namestring is a string which represents a pathname. The
+ syntax of namestrings for logical pathnames is well explained in the &ANSI;
+ and it can be roughly summarized as follows:
+
+ <synopsis><literal><optional><replaceable>hostname</replaceable>:</optional><optional>;</optional><optional><replaceable>directory-item</replaceable>;</optional><superscript>0 or more</superscript><optional><replaceable>name</replaceable></optional><optional>.<replaceable>type</replaceable><optional>.<replaceable>version</replaceable></optional></optional></literal>
+ <replaceable>hostname</replaceable> = <replaceable>word</replaceable>
+ <replaceable>directory-item</replaceable> = <replaceable>wildcard-word</replaceable>
+ <replaceable>type</replaceable>, <replaceable>name</replaceable> = <replaceable>wildcard-word</replaceable> without dots</synopsis>
+
+ Here, <replaceable>wildcard-word</replaceable> is a sequence of any
+ character excluding <literal>#\Null</literal> and
+ dots. <replaceable>word</replaceable> is like a
+ <replaceable>wildcard-word</replaceable> but asterisks are excluded.</para>
+
+ <para>The way &ECL; parses a namestring is by first looking for the
+ <replaceable>hostname</replaceable> component in the previous template. If
+ it is found and it corresponds to a previously defined logical hostname, it
+ assumes that the namestring corresponds to a logical pathname. If
+ <replaceable>hostname</replaceable> is not found or it is not a logical
+ hostname, then &ECL; tries the physical pathname syntax
+
+ <synopsis><literal><optional><replaceable>device</replaceable>:</optional><optional><optional>//<replaceable>hostname</replaceable></optional>/</optional><optional><replaceable>directory-item</replaceable>/</optional><superscript>0 or more</superscript><optional><replaceable>name</replaceable></optional><optional>.<replaceable>type</replaceable></optional></literal>
+ <replaceable>device</replaceable>, <replaceable>hostname</replaceable> = <replaceable>word</replaceable>
+ <replaceable>directory-item</replaceable> = <replaceable>wildcard-word</replaceable>
+ <replaceable>type</replaceable> = <replaceable>wildcard-word</replaceable> without dots
+ <replaceable>name</replaceable> = <optional>.</optional><replaceable>wildcard-word</replaceable></synopsis>
+
+ If this syntax also fails, then the namestring is not a valid pathname
+ string and a <type>parse-error</type> will be signalled.</para>
+
+ <para>It is important to remark that in &ECL;, all physical namestrings
+ result into pathnames with a version equal to
+ <literal>:NEWEST</literal>. Pathnames which are not logical and have any
+ other version (i. e. <literal>NIL</literal> or a number), cannot be printed
+ readably, but can produce a valid namestring which results of ignoring the
+ version.</para>
+
+ <para>Finally, an important rule applies to physical namestrings: if a
+ namestring contains one or more periods `.', the last period separates the
+ namestring into the file name and the filetype. However, a namestring with a
+ single leading period results in a name with a period in it. This is for
+ compatibility with Unix filenames such as <filename>.bashrc</filename>, where
+ the leading period indicates that the file is hidden.</para>
+
+ <para>The previous rule has in important consequence, because it means that
+ if you want to create a pathname without a name, you have to do it
+ explicitely. In other words, <literal>".*"</literal> is equivalent to
+ <code>(MAKE-PATHNAME :NAME ".*" :TYPE NIL)</code>, while <code>(MAKE-PATHNAME
+ :NAME NIL :TYPE :WILD)</code> creates a pathname whose type is a
+ wildcard.</para>
+
+ <para>The following table illustrates how the physical pathnames work with
+ practical examples.</para>
+ <table>
+ <title>Examples of physical namestrings</title>
+ <tgroup cols="3">
+ <thead>
+ <row><entry>Namestring</entry>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>Directory</entry>
+ <entry>Device</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>"foo.lsp"</entry>
+ <entry>"foo"</entry>
+ <entry>"lsp"</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ </row>
+ <row>
+ <entry>".bashrc"</entry>
+ <entry>".bashrc"</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ </row>
+ <row>
+ <entry>".ecl.lsp"</entry>
+ <entry>".ecl"</entry>
+ <entry>"lsp"</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ </row>
+ <row>
+ <entry>"foo.*"</entry>
+ <entry>"foo"</entry>
+ <entry>:WILD</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ </row>
+ <row>
+ <entry>"*.*"</entry>
+ <entry>:WILD</entry>
+ <entry>:WILD</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ </row>
+ <row>
+ <entry>"ecl/build/bare.lsp"</entry>
+ <entry>"bare"</entry>
+ <entry>"lsp"</entry>
+ <entry>(:relative "ecl" "build")</entry>
+ <entry>NIL</entry>
+ </row>
+ <row>
+ <entry>"ecl/build/"</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ <entry>(:relative "ecl" "build")</entry>
+ <entry>NIL</entry>
+ </row>
+ <row>
+ <entry>"../../ecl/build/"</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ <entry>(:relative :up :up "ecl" "build")</entry>
+ <entry>NIL</entry>
+ </row>
+ <row>
+ <entry>"/etc/"</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ <entry>(:absolute "etc")</entry>
+ <entry>NIL</entry>
+ </row>
+ <row>
+ <entry>"C:/etc/"</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ <entry>(:absolute "etc")</entry>
+ <entry>"C"</entry>
+ </row>
+ <row>
+ <entry>".*"</entry>
+ <entry>".*"</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ </row>
+ <row>
+ <entry>#.(MAKE-PATHNAME :TYPE "*")</entry>
+ <entry>NIL</entry>
+ <entry>:WILD</entry>
+ <entry>NIL</entry>
+ <entry>NIL</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section xml:id="ansi.pathnames.wild">
+ <title>Wild pathnames and matching</title>
+
+ <para>&ECL; accepts four kind of wildcards in pathnames.</para>
+ <itemizedlist>
+ <listitem>
+ <para>A single wildcard in a directory component, file name, type or
+ version is parsed as the <symbol>:WILD</symbol> value. See for instance
+ <literal>"*.*"</literal>, <literal>"/home/*/.bashrc"</literal>, etc</para>
+ </listitem>
+ <listitem>
+ <para>A double wildcard in a directory component, such as in
+ <literal>"/home/**/"</literal> is parsed as the
+ <symbol>:WILD-INFERIORS</symbol>, and matches any number of directories,
+ even nested ones, such as: <filename>/home/</filename>,
+ <filename>/home/jlr</filename>, <filename>/home/jlr/lib</filename>,
+ etc.</para>
+ </listitem>
+ <listitem>
+ <para>An isolated wildcard <literal>"log*.txt"</literal> matches any number
+ of characters: <filename>log.txt</filename>,
+ <filename>log_back.txt</filename>, etc.</para>
+ </listitem>
+ <listitem>
+ <para>A question mark <literal>"log?.txt"</literal> matches a single
+ character: <filename>log1.txt</filename>,
+ <filename>log2.txt</filename>...</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The matching rules in &CommonLisp; and &ECL; are simple but have some unintuitive consequences when compared to Unix/DOS rules. The most important one is that directories must always end with a trailing slash <literal>/</literal>, as in <literal>#p"/my/home/directory/"</literal>. Second to that, <symbol>NIL</symbol> values can only be matched by <symbol>NIL</symbol> and <symbol>:WILD</symbol>. Hence, <literal>"*"</literal> can only match files without file type. For some examples see <xref linkend="ansi.files.directory"/>.</para>
+ </section>
+
+ <xi:include href="ref_c_filenames.xml" xpointer="ansi.filenames.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.files">
+ <title>Files</title>
+
+ <section xml:id="ansi.files.dict">
+ <title>Dictionary</title>
+
+ <section xml:id="ansi.files.directory">
+ <title><function>DIRECTORY</function></title>
+
+ <para>This function does not have any additional arguments other than the
+ ones described in &ANSI;. To list files and directories, it follows the
+ rules for matching pathnames described in <xref
+ linkend="ansi.pathnames.wild"/>. In short, you have the following
+ practical examples:</para>
+ <table>
+ <title>Examples of using <function>DIRECTORY</function></title>
+ <tgroup cols="2">
+ <thead>
+ <row><entry>Argument</entry><entry>Meaning</entry></row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>"/home/jlr/*.*"</literal></entry>
+ <entry>List all files in directory <filename>/home/jlr/</filename> Note
+ that it lists only files, not directories!</entry>
+ </row>
+ <row>
+ <entry><literal>"/home/jlr/*"</literal></entry>
+ <entry>Same as before, but only files without type.</entry>
+ </row>
+ <row>
+ <entry><literal>"/home/jlr/*/"</literal></entry>
+ <entry>List all directories contained in
+ <filename>/home/jlr/</filename>. Nested directories are not
+ navigated.</entry>
+ </row>
+ <row>
+ <entry><literal>"/home/jlr/**/*.*"</literal></entry>
+ <entry>List all files in all directories contained in
+ <filename>/home/jlr/</filename>, recursively. Nested directories are
+ navigated.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ </section>
+
+ <xi:include href="ref_c_files.xml" xpointer="ansi.files.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.hash-tables">
+ <title>Hash tables</title>
+
+ <para>...</para>
+
+ <xi:include href="ref_c_hash_tables.xml" xpointer="ansi.hash-tables.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.numbers">
+ <title>Numbers</title>
+
+ <section xml:id="ansi.number-types">
+ <title>Numeric types</title>
+
+ <para>&ECL; supports all of the &CommonLisp; numeric tower, which is shown
+ in <xref linkend="table.ansi.numbers"/>. The details, however, depend both
+ on the platform on which &ECL; runs and on the configuration which was
+ chosen when building &ECL;.</para>
+ <table xml:id="table.ansi.numbers">
+ <title>Numeric types in &ECL;</title>
+ <tgroup cols="2">
+ <thead>
+ <row><entry>Type</entry><entry>Description</entry></row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>fixnum</type></entry>
+ <entry>Signed integer with a number of bits given by
+ <varname>ext:fixnum-bits</varname>, fit in a machine word.</entry>
+ </row>
+ <row>
+ <entry><type>bignum</type></entry>
+ <entry>Arbitrary size integers, only limited by amount of memory.</entry>
+ </row>
+ <row>
+ <entry><type>ratio</type></entry>
+ <entry>Arbitrary size rational number, made up of two integers.</entry>
+ </row>
+ <row>
+ <entry><type>short-float</type></entry>
+ <entry>Equivalent to <type>single-float</type>.</entry>
+ </row>
+ <row>
+ <entry><type>single-float</type></entry>
+ <entry>32-bits IEEE floating point number.</entry>
+ </row>
+ <row>
+ <entry><type>double-float</type></entry>
+ <entry>64-bits IEEE floating point number.</entry>
+ </row>
+ <row>
+ <entry><type>long-float</type></entry>
+ <entry>Either equivalent to <type>double-float</type>, or a 96/128 bits IEEE floating
+ point number (<type>long double</type> in C/C++).</entry>
+ </row>
+ <row>
+ <entry><type>rational</type></entry>
+ <entry>An alias for <type>(or integer ratio)</type></entry>
+ </row>
+ <row>
+ <entry><type>float</type></entry>
+ <entry>An alias for <type>(or single-float double-float short-float
+ long-float)</type></entry>
+ </row>
+ <row>
+ <entry><type>real</type></entry>
+ <entry>An alias for <type>(or real integer float)</type></entry>
+ </row>
+ <row>
+ <entry><type>complex</type></entry>
+ <entry>Complex number made of two real numbers of the above mentioned
+ types.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>In general, the size of a <type>FIXNUM</type> is determined by the
+ word size of a machine, which ranges from 32 to 64 bits. Integers larger
+ than this are implemented using the <ulink
+ url="http://www.swox.com/gmp/">GNU Multiprecision library</ulink>. Rationals
+ are implemented using two integers, without caring whether they are fixnum
+ or not. Floating point numbers include at least the two IEEE types of 32 and
+ 64 bits respectively. In machines where it is supported, it is possible to
+ associate the lisp <type>LONG-FLOAT</type> with the machine type <type>long
+ double</type> whose size ranges from 96 to 128 bits, and which are a bit
+ slower.</para>
+ </section>
+
+ <section xml:id="ansi.random-states">
+ <title>Random-States</title>
+
+ <para>&ECL; relies internally on a 32-bit or 64-bit Mersenne-Twister random number generator, using a relatively large buffer to precompute about 5000 pseud-random bytes. This implies also that random states can be printed readably and also read, using the <literal>#$</literal> macro. There is no provision to create random states from user arrays, though.</para>
+ </section>
+
+ <xi:include href="ref_c_numbers.xml" xpointer="ansi.numbers.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.objects">
+ <title>Objects</title>
+
+ <xi:include href="ref_c_objects.xml" xpointer="ansi.objects.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.overview">
+ <title>Overview</title>
+
+ <section>
+ <title>Reading this manual</title>
+
+ <section>
+ <title>Common Lisp users</title>
+
+ <para>&ECL; supports all Common-Lisp data types exactly as defined in the &ANSI;. All functions and macros are expected to behave as described in that document and in the HyperSpec &HyperSpec; which is the online version of &ANSI;. In other words, the Standard is the basic reference for Common Lisp and also for &ECL;, and this first part of the book just complements it, describing implementation-specific features such as
+ <itemizedlist>
+ <listitem><para>Platform dependent limits.</para></listitem>
+ <listitem><para>Behavior which is marked as <quote>implementation specific</quote> in the standard.</para></listitem>
+ <listitem><para>Some corner cases which are not described in &ANSI;.</para></listitem>
+ <listitem><para>The philosophy behind certain implementation choices, etc.</para></listitem>
+ </itemizedlist>
+ </para>
+
+ <para>In order to aid in locating these differences, this first part of the manual copies the structure of the &ANSI; standard, having the same number of chapters, each one with a set of sections documenting the implementation-specific details.</para>
+
+ </section>
+
+ <section>
+ <title>C/C++ programmers</title>
+
+ <para>The second goal of this document is to provide a reference for C programmers that want to create, manipulate and operate with Common Lisp programs at a lower level, or simply embedding &ECL; as a library.</para>
+
+ <para>The C/C++ reference evolves in parallel with the Common Lisp one, in the form of one section with the name "C Reference" for each chapter of the &ANSI; standard. Much of what is presented in those sections is redundant with the Common Lisp specification. In particular, there is a one-to-one mapping between types and functions which should be obvious given the rules explained in <xref linkend="ansi.overview.c-dict"/>.</para>
+
+ <para>We must remark that the reference in this part of the manual is not enough to know how to embed &ECL; in a program. In practice the user or developer will also have to learn how to <link linkend="ext.asdf">build programs</link>, <link linkend="ext.ffi">interface with foreign libraries</link>, <link linkend="ext.memory">manage memory</link>, etc. These concepts are explained in a different part of the book.</para>
+ </section>
+ </section>
+
+ <section xml:id="ansi.overview.c-dict">
+ <title>C Reference</title>
+
+ <section xml:id="cl_object">
+ <title>One type for everything: <type>cl_object</type></title>
+
+ <para>&ECL; is designed around the basic principle that Common Lisp already provides everything that a programmer could need, orienting itself around the creation and manipulation of Common Lisp objects: conses, arrays, strings, characters, ... When embedding &ECL; there should be no need to use other C/C++ types, except when interfacing data to and from those other languages.</para>
+
+ <para>All Common Lisp objects are represented internally through the same C type, <type>cl_object</type>, which is either a pointer to a union type or an integer, depending on the situation. While the inner guts of this type are exposed through various headers, the user should never rely on these details but rather use the macros and functions that are listed in this manual</para>
+
+ <para>There are two types of Common Lisp objects: immediate and memory allocated ones. Immediate types fit in the bits of the <type>cl_object</type> word, and do not require the garbage collector to be created. The list of such types may depend on the platform, but it includes at least the <type>fixnum</type> and <type>character</type> types.</para>
+
+ <para>Memory allocated types on the other hand require the use of the garbage collector to be created. &ECL; abstracts this from the user providing enough constructors, either in the form of Common Lisp functions (<function>cl_make_array()</function>, <function>cl_complex()</function>,...), or in the form of C/C++ constructors (<function>ecl_make_symbol()</function>, etc).</para>
+
+ <para>Memory allocated types must always be kept alive so that the garbage collector does not reclaim them. This involves referencing the object from one of the places that the collector scans:
+ <itemizedlist>
+ <listitem><para>The fields of an object (array, structure, etc) whic is itself alive.</para></listitem>
+ <listitem><para>A special variable or a constant.</para></listitem>
+ <listitem><para>The C stack (i.e. automatic variables in a function).</para></listitem>
+ <listitem><para>Global variables or pointers that have been registered with the garbage collector.</para></listitem>
+ </itemizedlist>
+ Further details will be provided in the section on <link linkend="ext.memory">Memory Management</link>.</para>
+ </section>
+
+ <section>
+ <title>Naming conventions</title>
+
+ <para>As explained in the introduction, each of the chapters in the Common Lisp standard can also be implemented using C functions and types. The mapping between both languages is done using a small set of rules described below.</para>
+ <itemizedlist>
+ <listitem><para>Functions in the Common Lisp ("CL") package are prefixed with the characters "cl_", functions in the System ("SI") package are prefix with "si_", etc, etc.</para></listitem>
+ <listitem><para>If a function takes only a fixed number of arguments, it is mapped to a C function with also a fixed number of arguments. For instance, <symbol>COS</symbol> maps to <code>cl_object cl_cos(cl_object)</code>, which takes a single Lisp object and returns a Lisp object of type <type>FLOAT</type>.</para></listitem>
+ <listitem><para>If the function takes a variable number of arguments, its signature consists on an integer with the number of arguments and zero or more of required arguments and then a C vararg. This is the case of <code>cl_object cl_list(cl_narg narg, ...)</code>, which can be invoked without arguments, as in <code>cl_list(0)</code>, with one, <code>cl_list(1, a)</code>, etc.</para></listitem>
+ <listitem><para>Functions return at least one value, which is either the first value output by the function, or <symbol>NIL</symbol>. The extra values may be retrieved immediately after the function call using the function <link linkend="ecl_nth_value"><function>ecl_nth_value</function></link>.</para></listitem>
+ </itemizedlist>
+ <para>In addition to the Common Lisp core functions (cl_*), there exist functions which are devoted only to C/C++ programming, with tasks such as coercion of objects to and from C types, optimized functions, inlined macroexpansions, etc. These functions and macros typically carry the prefix "ecl_" or "ECL_" and only return one value, if any.</para>
+ </section>
+
+ <section xml:id="ansi.OCL">
+ <title>Only in Common Lisp</title>
+
+ <para>Some parts of the language are not available as C functions, even though they can be used in Common Lisp programs. These parts are either marked in the "ANSI Dictionary" sections using the tag &OCL;, or they are simply not mentioned (macros and special constructs). This typically happens with non-translatable constructs such as</para>
+ <itemizedlist>
+ <listitem><para>Common Lisp macros such as <symbol>with-open-files</symbol>.</para></listitem>
+ <listitem><para>Common Lisp special forms, such as <symbol>cond</symbol></para></listitem>
+ <listitem><para>Common Lisp generic functions, which cannot be written in C because of their dynamical dispatch and automatic redefinition properties.</para></listitem>
+ </itemizedlist>
+
+ <para>In most of those cases there exist straightforward alternatives using the constructs and functions in &ECL;. For example, <symbol>unwind-protect</symbol> can be implemented using a C macro which is provided by &ECL;</para>
+<programlisting>
+cl_env_ptr env = ecl_process_env();
+CL_UNWIND_PROTECT_BEGIN(env) {
+ /* protected code goes here */
+} CL_UNWIND_PROTECT_EXIT {
+ /* exit code goes here */
+} CL_UNWIND_PROTECT_END;
+</programlisting>
+
+ <para>Common Lisp generic functions can be directly accessed using <symbol>funcall</symbol> or <symbol>apply</symbol> and the function name, as shown in the code below</para>
+<programlisting>
+cl_object name = ecl_make_symbol("MY-GENERIC-FUNCTION","CL-USER");
+cl_object output = cl_funcall(2, name, argument);
+</programlisting>
+
+ <para>Identifying these alternatives requires some knowledge of Common Lisp, which is why it is recommended to approach the embeddable components in &ECL; only when there is some familiarity with the language.</para>
+ </section>
+ </section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.packages">
+ <title>Packages</title>
+
+ <table xml:id="table.all-packages">
+ <title>ECL packages</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Nickname</entry>
+ <entry>In module</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><package>COMMON-LISP</package></entry>
+ <entry><package>CL</package>, <package>LISP</package></entry>
+ <entry>&ECL; core</entry>
+ <entry>Main &CommonLisp; package.</entry>
+ </row>
+ <row>
+ <entry><package>CLOS</package></entry>
+ <entry><package>MOP</package></entry>
+ <entry>&ECL; core</entry>
+ <entry>Symbols from the &AMOP;.</entry>
+ </row>
+ <row>
+ <entry><package>EXT</package></entry>
+ <entry></entry>
+ <entry>&ECL; core</entry>
+ <entry>&ECL; extensions to the language & library.</entry>
+ </row>
+ <row>
+ <entry><package>SYSTEM</package></entry>
+ <entry><package>SI</package>, <package>SYS</package></entry>
+ <entry>&ECL; core</entry>
+ <entry>Functions and variables internal to the implementation. Never to be used.</entry>
+ </row>
+ <row>
+ <entry><package>CMP</package></entry>
+ <entry><package>C</package></entry>
+ <entry><package>CMP</package></entry>
+ <entry>The compiler</entry>
+ </row>
+ <row>
+ <entry><package>XLIB</package></entry>
+ <entry><package>CLX</package></entry>
+ <entry><package>XLIB</package></entry>
+ <entry>CLX library for X-Windows</entry>
+ </row>
+ <row>
+ <entry><package>SB-BSD-SOCKETS</package></entry>
+ <entry></entry>
+ <entry><package>SOCKETS</package></entry>
+ <entry>Sockets library compatible with <acronym>SBCL</acronym>'s</entry>
+ </row>
+ <row>
+ <entry><package>SB-RT</package></entry>
+ <entry><package>RT</package>, <package>REGRESSION-TEST</package></entry>
+ <entry><package>RT</package></entry>
+ <entry>Test units (customized for &ECL;)</entry>
+ </row>
+ <row>
+ <entry><package>ASDF</package></entry>
+ <entry></entry>
+ <entry><package>ASDF</package></entry>
+ <entry>System definition file with &ECL; customizations.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>In <xref linkend="table.all-packages"/> we list all packages
+ available in &ECL;. The nicknames are aliases for a package. Thus,
+ <symbol>system:symbol</symbol> may be written as
+ <symbol>sys:symbol</symbol> or <symbol>si:symbol</symbol>. The module field
+ explains which library provides what package. For instance, the
+ <package>ASDF</package> is obtained when loading the
+ <package>ASDF</package> library with <code>(require 'asdf)</code>; and the
+ <package>XLIB</package> package when configuring and loading the
+ <package>CLX</package> library.</para>
+
+ <xi:include href="ref_c_packages.xml" xpointer="ansi.packages.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.printer">
+ <title>Printer</title>
+
+ <para>In all situations where the rules are well specified, &ECL; prints
+ objects according to &ANSI;. The specification leaves however a number of
+ cases as implementation dependent behavior. The output of &ECL; in those
+ cases is summarized in <xref linkend="table.printer"/>. Except for the types
+ <type>character</type> and <type>random-state</type>, most of those examples
+ regard non-standard written forms <literal>#<...></literal> cannot be
+ read back using <function>read</function>. These printed representations are
+ just informative and should not be used to reconstruct or compare
+ objects.</para>
+
+ <table xml:id="table.printer">
+ <title>Implementation specific printed representation</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Lisp type</entry>
+ <entry>Format</entry>
+ <entry>Remarks</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>package</type></entry>
+ <entry><literal>#<package <replaceable>name</replaceable>></literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><type>random-state</type></entry>
+ <entry><literal>#$<replaceable>character array</replaceable></literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><type>bitvector</type></entry>
+ <entry><literal>#<bit-vector <replaceable>unique-id</replaceable>></literal></entry>
+ <entry>Only when <varname>*print-array*</varname> is false.</entry>
+ </row>
+ <row>
+ <entry><type>vector</type></entry>
+ <entry><literal>#<vector <replaceable>unique-id</replaceable>></literal></entry>
+ <entry>Only when <varname>*print-array*</varname> is false.</entry>
+ </row>
+ <row>
+ <entry><type>array</type></entry>
+ <entry><literal>#<array <replaceable>unique-id</replaceable>></literal></entry>
+ <entry>Only when <varname>*print-array*</varname> is false.</entry>
+ </row>
+ <row>
+ <entry><type>hash-table</type></entry>
+ <entry><literal>#<hash-table <replaceable>unique-id</replaceable>></literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><type>readtable</type></entry>
+ <entry><literal>#<readtable <replaceable>unique-id</replaceable>></literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>interpreted <type>function</type></entry>
+ <entry><literal>#<bytecompiled-function <replaceable>name-or-id</replaceable>></literal></entry>
+ <entry>Name is a <type>symbol</type>.</entry>
+ </row>
+ <row>
+ <entry>machine compiled <type>function</type></entry>
+ <entry><literal>#<compiled-function <replaceable>name</replaceable>></literal></entry>
+ <entry>Name is a <type>symbol</type>.</entry>
+ </row>
+ <row>
+ <entry><type>input-stream</type></entry>
+ <entry><literal>#<input stream "<replaceable>filename</replaceable>"></literal></entry>
+ <entry>An stream that reads from <replaceable>filename</replaceable>.</entry>
+ </row>
+ <row>
+ <entry><type>output-stream</type></entry>
+ <entry><literal>#<output stream "<replaceable>filename</replaceable>"></literal></entry>
+ <entry>An stream that writes to <replaceable>filename</replaceable>.</entry>
+ </row>
+ <row>
+ <entry><type>probe-stream</type></entry>
+ <entry><literal>#<probe stream "<replaceable>filename</replaceable>"></literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><type>string-input-stream</type></entry>
+ <entry><literal>#<string-input stream from "<replaceable>string-piece</replaceable>"></literal></entry>
+ <entry>The string is the text left to be read.</entry>
+ </row>
+ <row>
+ <entry><type>string-output-stream</type></entry>
+ <entry><literal>#<string-output stream <replaceable>unique-id</replaceable>></literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><type>two-way-stream</type></entry>
+ <entry><literal>#<two-way stream <replaceable>unique-id</replaceable>></literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><type>echo-stream</type></entry>
+ <entry><literal>#<echo stream <replaceable>unique-id</replaceable>></literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><type>synonym-stream</type></entry>
+ <entry><literal>#<synonym stream to <replaceable>symbol</replaceable>></literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><type>broadcast-stream</type></entry>
+ <entry><literal>#<broadcast stream <replaceable>unique-id</replaceable>></literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><type>concatenated-stream</type></entry>
+ <entry><literal>#<concatenated stream <replaceable>unique-id</replaceable>></literal></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><type>closed-stream</type></entry>
+ <entry><literal>#<closed <replaceable>...</replaceable>></literal></entry>
+ <entry>The dots denote any of the above stream forms.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <xi:include href="ref_c_printer.xml" xpointer="ansi.printer.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.reader">
+ <title>Reader</title>
+
+ <xi:include href="ref_c_reader.xml" xpointer="ansi.reader.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.sequences">
+ <title>Sequences</title>
+
+ <xi:include href="ref_c_sequences.xml" xpointer="ansi.sequences.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.streams">
+ <title>Streams</title>
+
+ <section xml:id="ansi.streams.ansi">
+ <title>ANSI Streams</title>
+
+ <section xml:id="ansi.streams.types">
+ <title>Supported types</title>
+
+ <para>&ECL; implements all stream types described in &ANSI;. Additionally,
+ when configured with option <option>--enable-clos-streams</option>, &ECL;
+ includes a version of Gray streams where any object that implements the
+ appropiate methods (<function>stream-input-p</function>,
+ <function>stream-read-char</function>, etc) is a valid argument for the
+ functions that expect streams, such as <function>read</function>,
+ <function>print</function>, etc.</para>
+
+ </section>
+
+ <section xml:id="ansi.streams.io">
+ <title>Element types</title>
+
+ <para>&ECL; distinguishes between two kinds of streams: character streams and byte streams. <emphasis>Character streams</emphasis> only accept and produce characters, written or read one by one, with <function>write-char</function> or <function>read-char</function>, or in chunks, with <function>write-sequence</function> or any of the Lisp printer functions. Character operations are conditioned by the external format, as described in <xref linkend="ansi.streams.formats"/></para>
+
+ <para>ANSI Common Lisp also supports binary streams. Here input and output is performed in chunks of bits. Binary streams are created with the function <function>open</function> passing as argument a subtype of <type>integer</type> and the implementation is free to round up that integer type to the closest size it supports. In particular &ECL; rounds up the size to a multiple of a byte. For example, the form <code>(open "foo.bin" :direction :output :element-type '(unsigned-byte 13))</code>, will open the file <filename>foo.bin</filename> for writing, using 16-bit words as the element type.</para>
+ </section>
+
+ <section xml:id="ansi.streams.formats">
+ <title>External formats</title>
+
+ <para>An <emphasis>external format</emphasis> is an encoding for characters that maps character codes to a sequence of bytes, in a one-to-one or one-to-many fashion. External formats are also known as "character encodings" in the programming world and are an essential ingredient to be able to read and write text in different languages and alphabets.</para>
+
+ <para>&ECL; has one of the most complete supports for <emphasis>external formats</emphasis>, covering all of the usual codepages from the Windows and Unix world, up to the more recent <acronym>UTF-8</acronym>, <acronym>UCS-2</acronym> and <acronym>UCS-4</acronym> formats, all of them with big and small endian variants, and considering different encodings for the newline character.</para>
+
+ <para>However, the set of supported external formats depends on the size of the space of character codes. When &ECL; is built with Unicode support (the default option), it can represent all known characters from all known codepages, and thus all external formats are supported. However, when &ECL; is built with the restricted character set, it can only use one codepage (the one provided by the C library), with a few variants for the representation of end-of-line characters.</para>
+
+ <para>In &ECL;, an external format designator is defined recursively as either a symbol or a list of symbols. The grammar is as follows
+<screen>external-format-designator :=
+ symbol |
+ ( {symbol}+ )
+</screen>
+and the table of known symbols is shown below. Note how some symbols (<code>:cr</code>, <code>:little-endian</code>, etc) just modify other external formats.</para>
+
+<table xml:id="table.external-formats">
+ <title>Stream external formats</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Symbols</entry>
+ <entry>Codepage or encoding</entry>
+ <entry>Unicode required</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><symbol>:cr</symbol></entry>
+ <entry><code>#\Newline</code> is Carriage Return</entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry><symbol>:crlf</symbol></entry>
+ <entry><code>#\Newline</code> is Carriage Return followed by Linefeed</entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry><symbol>:lf</symbol></entry>
+ <entry><code>#\Newline</code> is Linefeed</entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry><symbol>:little-endian</symbol></entry>
+ <entry>Modify <acronym>UCS</acronym> to use little endian encoding.</entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry><symbol>:big-endian</symbol></entry>
+ <entry>Modify <acronym>UCS</acronym> to use big endian encoding.</entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry><symbol>:utf-8</symbol> <symbol>ext:utf8</symbol></entry>
+ <entry>Unicode <acronym>UTF-8</acronym></entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>:ucs-2</symbol> <symbol>ext:ucs2</symbol> <symbol>ext:utf-16</symbol> <symbol>ext:utf16</symbol>
+<symbol>ext:unicode</symbol></entry>
+ <entry><acronym>UCS-2</acronym> encoding with <acronym>BOM</acronym>.</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>:ucs-2le</symbol> <symbol>ext:ucs2le</symbol> <symbol>ext:utf-16le</symbol></entry>
+ <entry><acronym>UCS-2</acronym> with big-endian encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>:ucs-2be</symbol> <symbol>ext:ucs2be</symbol> <symbol>ext:utf-16be</symbol></entry>
+ <entry><acronym>UCS-2</acronym> with big-endian encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>:ucs-4</symbol> <symbol>ext:ucs4</symbol> <symbol>ext:utf-32</symbol> <symbol>ext:utf32</symbol></entry>
+ <entry><acronym>UCS-4</acronym> encoding with <acronym>BOM</acronym>.</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>:ucs-4le</symbol> <symbol>ext:ucs4le</symbol> <symbol>ext:utf-32le</symbol></entry>
+ <entry><acronym>UCS-4</acronym> with big-endian encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>:ucs-4be</symbol> <symbol>ext:ucs4be</symbol> <symbol>ext:utf-32be</symbol></entry>
+ <entry><acronym>UCS-4</acronym> with big-endian encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-1</symbol> <symbol>ext:iso8859-1</symbol> <symbol>ext:latin-1</symbol> <symbol>ext:cp819</symbol> <symbol>ext:ibm819</symbol></entry>
+ <entry>Latin-1 encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-2</symbol> <symbol>ext:iso8859-2</symbol> <symbol>ext:latin-2</symbol> <symbol>ext:latin2</symbol></entry>
+ <entry>Latin-2 encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-3</symbol> <symbol>ext:iso8859-3</symbol> <symbol>ext:latin-3</symbol> <symbol>ext:latin3</symbol></entry>
+ <entry>Latin-3 encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-4</symbol> <symbol>ext:iso8859-4</symbol> <symbol>ext:latin-4</symbol> <symbol>ext:latin4</symbol></entry>
+ <entry>Latin-4 encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-5</symbol> <symbol>ext:cyrillic</symbol></entry>
+ <entry>Latin-5 encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-6</symbol> <symbol>ext:arabic</symbol> <symbol>ext:asmo-708</symbol> <symbol>ext:ecma-114</symbol></entry>
+ <entry>Latin-6 encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-7</symbol> <symbol>ext:greek8</symbol> <symbol>ext:greek</symbol> <symbol>ext:ecma-118</symbol></entry>
+ <entry>Greek encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-8</symbol> <symbol>ext:hebrew</symbol></entry>
+ <entry>Hebrew encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-9</symbol> <symbol>ext:latin-5</symbol> <symbol>ext:latin5</symbol></entry>
+ <entry>Latin-5 encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-10</symbol> <symbol>ext:iso8859-10</symbol> <symbol>ext:latin-6</symbol> <symbol>ext:latin6</symbol></entry>
+ <entry>Latin-6 encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-13</symbol> <symbol>ext:iso8859-13</symbol> <symbol>ext:latin-7</symbol> <symbol>ext:latin7</symbol></entry>
+ <entry>Latin-7 encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-14</symbol> <symbol>ext:iso8859-14</symbol> <symbol>ext:latin-8</symbol> <symbol>ext:latin8</symbol></entry>
+ <entry>Latin-8 encoding</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:iso-8859-15</symbol> <symbol>ext:iso8859-15</symbol> <symbol>ext:latin-9</symbol> <symbol>ext:latin9</symbol></entry>
+ <entry>Latin-7 encoding</entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry><symbol>ext:dos-cp437</symbol> <symbol>ext:ibm-437</symbol></entry>
+ <entry>IBM CP 437</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:dos-cp850</symbol> <symbol>ext:ibm-850</symbol> <symbol>ext:cp850</symbol></entry>
+ <entry>Windows CP 850</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:dos-cp852</symbol> <symbol>ext:ibm-852</symbol></entry>
+ <entry>IBM CP 852</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:dos-cp855</symbol> <symbol>ext:ibm-855</symbol></entry>
+ <entry>IBM CP 855</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:dos-cp860</symbol> <symbol>ext:ibm-860</symbol></entry>
+ <entry>IBM CP 860</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:dos-cp861</symbol> <symbol>ext:ibm-861</symbol></entry>
+ <entry>IBM CP 861</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:dos-cp862</symbol> <symbol>ext:ibm-862</symbol> <symbol>ext:cp862</symbol></entry>
+ <entry>Windows CP 862</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:dos-cp863</symbol> <symbol>ext:ibm-863</symbol></entry>
+ <entry>IBM CP 863</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:dos-cp864</symbol> <symbol>ext:ibm-864</symbol></entry>
+ <entry>IBM CP 864</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:dos-cp865</symbol> <symbol>ext:ibm-865</symbol></entry>
+ <entry>IBM CP 865</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:dos-cp866</symbol> <symbol>ext:ibm-866</symbol> <symbol>ext:cp866</symbol></entry>
+ <entry>Windows CP 866</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:dos-cp869</symbol> <symbol>ext:ibm-869</symbol></entry>
+ <entry>IBM CP 869</entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry><symbol>ext:windows-cp932</symbol> <symbol>ext:windows-932</symbol> <symbol>ext:cp932</symbol></entry>
+ <entry>Windows CP 932</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:windows-cp936</symbol> <symbol>ext:windows-936</symbol> <symbol>ext:cp936</symbol></entry>
+ <entry>Windows CP 936</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:windows-cp949</symbol> <symbol>ext:windows-949</symbol> <symbol>ext:cp949</symbol></entry>
+ <entry>Windows CP 949</entry>
+ <entry>Yes</entry>
+ </row>
+ <row>
+ <entry><symbol>ext:windows-cp950</symbol> <symbol>ext:windows-950</symbol> <symbol>ext:cp950</symbol></entry>
+ <entry>Windows CP 950</entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry><symbol>ext:windows-cp1250</symbol> <symbol>ext:windows-1250</symbol> <symbol>ext:ms-ee</symbol></entry>
+ <entry>Windows CP 1250</entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry><symbol>ext:windows-cp1251</symbol> <symbol>ext:windows-1251</symbol> <symbol>ext:ms-cyrl</symbol></entry>
+ <entry>Windows CP 1251</entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry><symbol>ext:windows-cp1252</symbol> <symbol>ext:windows-1252</symbol> <symbol>ext:ms-ansi</symbol></entry>
+ <entry>Windows CP 1252</entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry><symbol>ext:windows-cp1253</symbol> <symbol>ext:windows-1253</symbol> <symbol>ext:ms-greek</symbol></entry>
+ <entry>Windows CP 1253</entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry><symbol>ext:windows-cp1254</symbol> <symbol>ext:windows-1254</symbol> <symbol>ext:ms-turk</symbol></entry>
+ <entry>Windows CP 1254</entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry><symbol>ext:windows-cp1255</symbol> <symbol>ext:windows-1255</symbol> <symbol>ext:ms-hebr</symbol></entry>
+ <entry>Windows CP 1255</entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry><symbol>ext:windows-cp1256</symbol> <symbol>ext:windows-1256</symbol> <symbol>ext:ms-arab</symbol></entry>
+ <entry>Windows CP 1256</entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry><symbol>ext:windows-cp1257</symbol> <symbol>ext:windows-1257</symbol> <symbol>ext:winbaltrim</symbol></entry>
+ <entry>Windows CP 1257</entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry><symbol>ext:windows-cp1258</symbol> <symbol>ext:windows-1258</symbol></entry>
+ <entry>Windows CP 1258</entry>
+ <entry>Yes</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</table>
+
+ </section>
+ </section>
+
+ <xi:include href="ref_c_streams.xml" xpointer="ansi.streams.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.strings">
+ <title>Strings</title>
+
+ <section xml:id="ansi.strings.types">
+
+ <title>String types & Unicode</title>
+
+ <para>The &ECL; implementation of strings is ANSI Common-Lisp compliant. There are basically four string types as shown in <xref linkend="table.ansi.strings"/>. As explained in <xref linkend="ansi.characters"/>, when Unicode support is disabled, <type>character</type> and <type>base-character</type> are the same type and the last two string types are equivalent to the first two.</para>
+ <table xml:id="table.ansi.strings">
+ <title>&CommonLisp; string types</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Abbreviation</entry>
+ <entry>Expanded type</entry>
+ <entry>Remarks</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>string</type></entry>
+ <entry><type>(array character (*))</type></entry>
+ <entry>8 or 32 bits per character, adjustable.</entry>
+ </row>
+ <row>
+ <entry><type>simple-string</type></entry>
+ <entry><type>(simple-array character (*))</type></entry>
+ <entry>8 or 32 bits per character, not adjustable nor displaced.</entry>
+ </row>
+ <row>
+ <entry><type>base-string</type></entry>
+ <entry><type>(array base-char (*))</type></entry>
+ <entry>8 bits per character, adjustable.</entry>
+ </row>
+ <row>
+ <entry><type>simple-base-string</type></entry>
+ <entry><type>(simple-array base-char (*))</type></entry>
+ <entry>8 bits per character, not adjustable nor displaced.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>It is important to remember that strings with unicode characters can only be printed readably when the external format supports those characters. If this is not the case, &ECL; will signal a <type>serious-condition</type>. This condition will abort your program if not properly handled.</para>
+
+ </section>
+
+<xi:include href="ref_c_strings.xml" xpointer="ansi.strings.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.structures">
+ <title>Structures</title>
+
+ <xi:include href="ref_c_structures.xml" xpointer="ansi.structures.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.symbols">
+ <title>Symbols</title>
+ <para>There are no implementation-specific limits on the size or content of
+ symbol names. It is however not allowed to write on the strings which have
+ been passed to #'make-symbol or returned from #'symbol-name.</para>
+
+ <xi:include href="ref_c_symbols.xml" xpointer="ansi.symbols.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.system-construction">
+ <title>System Construction</title>
+
+ <xi:include href="ref_c_system_construction.xml" xpointer="ansi.system-construction.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ansi.types-and-classes">
+ <title>Types and classes</title>
+
+ <xi:include href="ref_c_types_and_classes.xml" xpointer="ansi.types-and-classes.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ext.asdf">
+ <title>System building</title>
+
+ <section xml:id="ext.asdf.intro">
+ <title>Introduction</title>
+
+ <para>A typical application will consist of multiple lisp files that have to
+ be compiled and which will probably be linked to additional, third party
+ libraries, either written themselves in &CommonLisp; or shipped as foreign C
+ or C++ dynamically or statically linked lirbaries. Not only loading these
+ files into a running &ECL; can be a slow process in some platforms, but
+ shipping code in the form of multiple binaries and a script to load them is
+ far from optimal.</para>
+
+ <para>Traditionally, &CommonLisp; implemenations have provided a function to
+ save the dump all data from a running Lisp process into a file. The result
+ was called the Lisp image and could be shipped to other version compatible
+ implementations.Nowadays, having less control of the systems it runs in, a Lisp
+ implementation must work very hard to dump memory images and be able to load
+ and execute them afterwards.</para>
+
+ <para>&ECL; has chosen to avoid this process entirely. Instead, we conceive
+ five different portable models for building and shippin your programs. The
+ models, described in <xref linkend="table.make-build"/>, enumerate the
+ different kinds of files that &ECL; can portably produce. To get one or more
+ of the products mentioned in the table, you may resort to a low level
+ <acronym>API</acronym> described in <xref
+ linkend="part.internals"/>. However, we recommend a simpler way based on
+ using System Definition Files to describe the structure of your project and
+ let &ECL; build the desired target for you. This approach is described in the
+ following sections.</para>
+
+ <table xml:id="table.make-build">
+ <title>Code distribution models</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Model</entry>
+ <entry>Description</entry>
+ <entry><symbol>:TYPE</symbol></entry>
+ <entry><symbol>:MONOLITHIC</symbol></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Source code</entry>
+ <entry><para>You distribute your programs in source code form. This is
+ the easiest and most portable way, but not the fastest
+ one.</para></entry>
+ <entry>NA</entry>
+ <entry>NA</entry>
+ </row>
+ <row>
+ <entry>&FASL; or loadable file</entry>
+ <entry><para>Best suited for development. You translate all lisp code to
+ C and link it against possibly other C/C++ libraries to obtain a single
+ binary file with extension <filename>.fas</filename>, like the compiled
+ files you obtain from using <function>compile-file</function>. This
+ "unified" &FASL; can be loaded a startup time to add new functionality to
+ the &ECL; environment.</para></entry>
+ <entry><symbol>:FASL</symbol></entry>
+ <entry><symbol>T</symbol>/<symbol>NIL</symbol></entry>
+ </row>
+ <row>
+ <entry>Standalone program</entry>
+ <entry><para>Product shipping for final user. You translate all your lisp
+ code to C using the &ECL; compiler. The final object files can be linked
+ against other C/C++ libraries to obtain a standalone executable.</para></entry>
+ <entry><symbol>:PROGRAM</symbol></entry>
+ <entry>T</entry>
+ </row>
+ <row>
+ <entry>Statically linked library</entry>
+ <entry><para>For embedding purposes. You translate all your lisp code to
+ C and combine the resulting object files into a single library with
+ <filename>.a</filename> or <filename>.lib</filename> extension. You can
+ distribute this library to other people and the final users can utilize
+ these libraries to build standalone programs.</para></entry>
+ <entry><symbol>:LIB</symbol></entry>
+ <entry><symbol>T</symbol>/<symbol>NIL</symbol></entry>
+ </row>
+ <row>
+ <entry>Dynamically linked library</entry>
+ <entry><para>For embedding purposes. Similar to a statically linked
+ library, but it is loaded at run time by the operating system and can be
+ shared by more than one instance of a program.</para></entry>
+ <entry><symbol>:LIB</symbol></entry>
+ <entry><symbol>T</symbol>/<symbol>NIL</symbol></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </section>
+
+ <section xml:id="ext.asdf.sdf">
+ <title>System definition files</title>
+
+ <para>A System Definition File, or just <emphasis>system</emphasis>, is the
+ lisp equivalent of a makefile in the Unix world: it contains a list of source
+ files which are to be loaded or compiled, and dependencies among them ("load
+ source <filename>file1.lsp</filename> before compiling
+ <filename>file2.lsp</filename>", etc).</para>
+
+ <para>It is difficult to tell about the Lisp Machines history, but probably
+ the first most popular system definition format was called
+ <application>mk-defsystem</application> or simply
+ <application>defsystem</application>. Written by Mark Kantrowitz [<xref
+ linkend="bib.mk-defsystem"/>], this library now lives in the <ulink
+ url="https://sourceforge.net/projects/clocc/">CLOCC</ulink> repository and is
+ actively maintained. &ECL; ships with a copy of the version 3.x which
+ fortunately has no customizations. You can load this copy by issuing
+ <code>(require 'defsystem)</code> from the lisp toplevel.</para>
+
+ <para>However, in the last years, Another System Definition Facility known as
+ &ASDF; has become even more popular in the &CommonLisp; world. This new
+ format simplifies writing extensions to handle new kind of source files and
+ integrates very well with the package management utility known as
+ <application>ASDF-install</application>. &ASDF; has a slightly different
+ syntax from <application>mk-defsystem 3.0</application>, but because of
+ reasons of popularity and better integration with &ECL;, in this manual we
+ have focused on this particular library.</para>
+
+ <para>A simple &ASDF; definition looks as follows:</para>
+<programlisting>
+(defsystem test
+ :source-pathname "~/src/test/"
+ :source-extension "lisp"
+ :components ((:module file1
+ :source-pathname "")
+ (:module file2
+ :source-pathname ""
+ :depends-on (file1))))</programlisting>
+ <para>This example consists of two files, <filename>file1.lisp</filename> and
+ <filename>file2.lisp</filename>, located in
+ <filename>~/src/test/</filename>. When compiling these files,
+ <filename>file1.lisp</filename> will be processed before
+ <filename>file2.lisp</filename>, because the second depends on the former
+ one. There are more complex rules that allow a system to depend on others,
+ and to contain other kind of files, such as C or Java binaries. For further
+ information we recommend reading <ulink
+ url="http://constantly.at/lisp/asdf/">the online manual</ulink>.</para>
+
+ <para>You can load &ASDF; on a running &ECL; using a single lisp statement
+ <code>(require 'asdf)</code>. Once loaded, &ASDF; will extend the function
+ <function>require</function> to recognize and load libraries that are placed
+ in standard locations or which have been registered with &ASDF; itself. The
+ following sections describe other features of &ASDF; which are specific to
+ &ECL; and related to the code building and shipping mechanisms introduced
+ before.</para>
+ </section>
+
+ <section xml:id="ext.asdf.make-build">
+ <title>Practical examples</title>
+
+ <para>The version of &ASDF; which is shipped with &ECL; has been further
+ customized to allow building all the binary files mentioned in <xref
+ linkend="table.make-build"/>. The procedure to do this is documented in a
+ detailed and formal manual page for <xref
+ linkend="ref.make-build"/>. However, since practice is the best teacher, we
+ will show a couple of examples of how to use this function before moving into
+ the formal specification.</para>
+
+ <para>In <filename>/ecl/examples/asdf</filename> you will find a very simple
+ example that can be built in different forms. The example is built around a
+ system definition file that depends on two sources,
+ <filename>file1.lisp</filename> and <filename>file2.lisp</filename>:</para>
+ <programlisting>
+(defsystem #:example
+ :serial t
+ :components ((:file "file1")
+ (:file "file2")))</programlisting>
+
+ <para>We can built these files into a single &FASL; file, as shown
+ below. Notice how there is a single file with the name
+ <filename>*.fas</filename>, but there are two object files generated from
+ their respective sources, <filename>file1.o</filename>,
+ <filename>file2.o</filename>.</para>
+<screen>
+> (require 'asdf)
+;;; Loading #P"/home/jlr/lib/ecl/asdf.fas"
+("ASDF")
+> (asdf:make-build :example :type :fasl)
+...
+NIL
+> (directory "*.o")
+(#P"/home/jlr/src/ecls-new/examples/asdf/file2.o"
+ #P"/home/jlr/src/ecls-new/examples/asdf/file1.o")
+> (directory "*.fas")
+(#P"/home/jlr/src/ecls-new/examples/asdf/example.fas")
+> (load "example.fas")
+;;; Loading "/home/jlr/src/ecls-new/examples/asdf/example.fas"
+======================================================================
+We are now executing FILE1.LSP
+TEST-FUNCTION has been created
+We are now executing FILE2.LSP
+Calling TEST-FUNCTION in FILE2.LSP
+1 + 1 is equal to 2
+Finished
+======================================================================
+"/home/jlr/src/ecls-new/examples/asdf/example.fas"
+</screen>
+
+ <para>The previous sources may be combined into a single program, as shown
+ below. Notice that we choose to execute <function>ext:quit</function> right
+ after all compiled files have run. If you do not supply this parameter,
+ <filename>example</filename> will jump to the lisp toplevel right after
+ that.</para>
+<screen>
+> (asdf:make-build :example :type :program
+ :epilogue-code '(ext:quit 0))
+NIL
+> (ext:system "./example")
+======================================================================
+We are now executing FILE1.LSP
+TEST-FUNCTION has been created
+We are now executing FILE2.LSP
+Calling TEST-FUNCTION in FILE2.LSP
+1 + 1 is equal to 2
+Finished
+======================================================================</screen>
+
+ </section>
+
+ <section xml:id="ext.asdf.dict">
+ <title>ASDF Reference</title>
+
+<!-- ====================================================================== -->
+<!-- ASDF:MAKE-BUILD -->
+<!-- ====================================================================== -->
+
+ <refentry xml:id="ref.make-build">
+ <refnamediv>
+ <refname><function>asdf:make-build</function></refname>
+ <refpurpose>Block-build an &ASDF; system definition</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>asdf:make-build</funcdef>
+ <paramdef><parameter>system-name</parameter></paramdef>
+ <paramdef>&key;</paramdef>
+ <paramdef><parameter>type</parameter></paramdef>
+ <paramdef><parameter>monolithic</parameter></paramdef>
+ <paramdef><parameter>ld-flags</parameter></paramdef>
+ <paramdef><parameter>prologue-code</parameter></paramdef>
+ <paramdef><parameter>epilogue-code</parameter></paramdef>
+ <paramdef>&allow-other-keys;</paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>system-name</replaceable></term>
+ <listitem><para>A symbol naming the system to be built. Only the symbol
+ name is considered.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>type</replaceable></term>
+ <listitem><para>One of <symbol>:FASL</symbol>, <symbol>:DLL</symbol>,
+ <symbol>:LIB</symbol> or
+ <symbol>:PROGRAM</symbol></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>monolithic</replaceable></term>
+ <listitem><para>A boolean value.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>ld-flags</replaceable></term>
+ <listitem><para>A list of strings.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>prologue-code</replaceable></term>
+ <listitem><para>A string.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>epilogue-code</replaceable></term>
+ <listitem><para>A string or a lisp form.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This function takes a system definition which is known to &ASDF; and
+ builds one or more binary files, depending on the arguments. The possible
+ output files depend on the value of <varname>type</varname> and are
+ summarized in <xref linkend="table.make-build"/>.</para>
+
+ <para>Internally the function works similary to the
+ &ASDF; function <function>asdf:oos</function> with the
+ <function>asdf:load-op</function> operator. It finds out the requested
+ system definition, either by searching in a set of predefined locations or
+ because the system has been already loaded into memory, computes all
+ libraries and components this system depends on, builds them and then
+ produces the desired output.</para>
+
+ <para>If the value of <varname>:monolithic</varname> is
+ <varname>NIL</varname> the output binary will contain just the desired
+ system, while in other cases the output will be linked together with all
+ libraries your system depends on. Standalone executables, given by
+ <code>type = :program</code>, must, by definition, be monolithic. All other
+ systems need not, but in that case you will have to manually satisfy the
+ required dependencies when using those files.</para>
+
+ <para>This function takes additional values which are related to the low
+ level details of the produced binaries. First of all we find
+ <varname>ld-flags</varname>, a list of strings with arguments for the
+ object linker. You will only need this argument if you have to link your
+ programs with foreign libraries.</para>
+
+ <para>The next two arguments represent two pieces of code which are
+ executed before (<varname>prologue-code</varname>) and after
+ (<varname>epilogue-code</varname>) running your lisp code. The prologue
+ code is a string with C code which you will typically use to initialize
+ foreign libraries. It can only be C code because this code may be executed
+ even before &ECL; itself is initialized.</para>
+
+ <para>The epilogue code, on the other hand, can be either a string with C
+ statements or a lisp form represented as a list. In the case of executables
+ it conveniently defaults to a call to the toplevel
+ <code>(SI::TOP-LEVEL)</code>, while in the case of libraries and &FASL;
+ files it is left empty.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>See <xref linkend="ext.asdf.make-build"/>.</para></refsect1>
+ </refentry>
+
+<!-- ====================================================================== -->
+<!-- ASDF:MAKE-BUILD -->
+<!-- ====================================================================== -->
+
+ <refentry xml:id="ref.load-fasl-op">
+ <refnamediv>
+ <refname><function>asdf:load-fasl-op</function></refname>
+ <refpurpose>Compile and load one ore more libraries using unified &FASL;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>&ASDF; operator</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>asdf:make-build</funcdef>
+ <paramdef>'asdf:load-fasl-op</paramdef>
+ <paramdef><parameter>system-name</parameter></paramdef>
+ <paramdef>&key;</paramdef>
+ <paramdef>&allow-other-keys;</paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>system-name</replaceable></term>
+ <listitem><para>A symbol naming the system to be built. Only the symbol
+ name is considered.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This function is a replacement for the &ASDF; operator
+ <symbol>ASDF:LOAD-OP</symbol>. Given a system name, it will build it and
+ all its dependencies, to load them in the required order. The only
+ difference with respect to <symbol>ASDF:LOAD-OP</symbol> is that it builds
+ a single &FASL; file per module, thus being potentially faster and more
+ resource efficient.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>Assume you want to load the &CFFI; library, which has been registered
+ with &ASDF;. You will simply type</para>
+<screen>
+> (require 'asdf)
+;;; Loading #P"/home/jlr/lib/ecl/asdf.fas"
+("ASDF")
+> (asdf:oos 'asdf:load-fasl-op :cffi)
+...
+T
+</screen>
+ </refsect1>
+ </refentry>
+
+ </section>
+ </chapter>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+ -->
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <bibliography xml:id="Bibliography">
+ <title>Bibliography</title>
+
+ <bibliomixed xml:id="bib.LISP1.5" xreflabel="LISP1.5">
+ <bibliomset>
+ <firstname>John</firstname> <surname>McCarthy</surname> et
+ al. <title>LISP 1.5 Programmer's
+ Manual 2nd ed</title> <publishername>The M.I.T. Press</publishername>,
+ <corpname>Massachussets Institute of Technology</corpname>,
+ <pubdate>1985</pubdate>.
+
+ <bibliomisc>Available at the <ulink
+ url="http://community.computerhistory.org/scc/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf">Computer
+ History Museum Communities Site</ulink></bibliomisc>
+ </bibliomset>
+ </bibliomixed>
+
+ <bibliomixed xml:id="bib.ANSI" xreflabel="ANSI">
+ <bibliomset>
+ <title>ANSI Common Lisp Specification, ANSI/X3.226-1994</title>.
+ <corpname>American National Standards Institute</corpname>,
+ <pubdate>1994</pubdate>.
+ </bibliomset>
+ </bibliomixed>
+
+ <bibliomixed xml:id="bib.HyperSpec" xreflabel="CLHS">
+ <bibliomset>
+ <firstname>Kent M.</firstname> <surname>Pitman</surname>.
+ <title>The Common Lisp Hyperspec</title>.
+ <corpname>Lispworks</corpname>, <pubdate>1996</pubdate>.
+ <bibliomisc>Available in the <ulink
+ url="http://www.lispworks.com/documentation/HyperSpec/Front/index.htm">Lispworks
+ homepage</ulink>.</bibliomisc>
+ </bibliomset>
+ </bibliomixed>
+
+ <bibliomixed xml:id="bib.CLTL" xreflabel="CLTL">
+ <bibliomset>
+ <firstname>Guy L.</firstname> <surname>Steele Jr</surname> et al.
+ <title>Common Lisp The Language</title>.
+ <publishername>Digital Press</publishername>, <pubdate>1984</pubdate>.
+ </bibliomset>
+ </bibliomixed>
+
+ <bibliomixed xml:id="bib.CLTL2" xreflabel="CLTL2">
+ <bibliomset>
+ <firstname>Guy L.</firstname> <surname>Steele Jr.</surname> et al.
+ <title>Common Lisp The Language II</title>.
+ <publishername>Digital Press</publishername>, <pubdate>1990</pubdate>.
+ </bibliomset>
+ </bibliomixed>
+
+ <bibliomixed xml:id="bib.KCL" xreflabel="KCL">
+ <bibliomset>
+ <firstname>Taichi</firstname> <surname>Yuasa</surname> and
+ <firstname>Masami</firstname> <surname>Hagiya</surname>. <title>Kyoto
+ Common Lisp Report</title>. <corpname>Research Institute for Mathematical
+ Sciences, Kyoto University</corpname>, <pubdate>1988</pubdate>.
+ </bibliomset>
+ </bibliomixed>
+
+ <bibliomixed xml:id="bib.ECL" xreflabel="ECL">
+ <bibliomset>
+ <firstname>Giusseppe</firstname> <surname>Attardi</surname>. <title>The
+ Embeddable Common Lisp</title>. <publishername>ACM Lisp
+ Pointers</publishername>, <volumenum>8(1)</volumenum>,
+ <pagenums>30-41</pagenums>, <pubdate>1995</pubdate>.
+ </bibliomset>
+ </bibliomixed>
+
+ <bibliomixed xml:id="bib.mk-defsystem" xreflabel="mk-defsystem">
+ <bibliomset>
+ <firstname>Mark</firstname> <surname>Kantrowitz</surname>, <title>Portable
+ Utilities for Common Lisp. User Guide & Implementation.</title>
+ <corpname>Cargnegie Mellon University</corpname>, <pubdate>1991</pubdate>.
+ <bibliomisc>Available in the <ulink
+ url="http://www-2.cs.cmu.edu/afs/cs.cmu.edu/project/ai-repository/ai/lang/lisp/code/tools/mkantdoc.tgz">CMU
+ repository</ulink></bibliomisc>
+ </bibliomset>
+ </bibliomixed>
+
+ <bibliomixed xml:id="bib.AMOP" xreflabel="AMOP">
+ <bibliomset>
+ <firstname>Gregor</firstname> <surname>Kickzales</surname> et al. <title>The
+ Art of the Metaobject Protocol</title> <publishername>The
+ M.I.T. Press</publishername>, <corpname>Massachussets Institute of
+ Technology</corpname>, <pubdate>1999</pubdate>.
+ </bibliomset>
+ </bibliomixed>
+
+
+ </bibliography>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+-->
+</book>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter label="11" xml:id="CLOS">
+<title>CLOS</title>
+<blockquote>
+<screen><indexterm role="fn"><primary>add-method</primary></indexterm>— Generic: <function>add-method</function> <varname>generic-function</varname> <varname>method</varname></screen>
+<screen><indexterm role="fn"><primary>add-method</primary></indexterm>— Method: <function>add-method</function> (</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>call-method</primary></indexterm>— Macro: <function>call-method</function> <varname>method next-method-list</varname></screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>call-next-method</primary></indexterm>— Macro: <function>call-next-method</function> <varname>&rest args</varname></screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>change-class</primary></indexterm>— Generic: <function>change-class</function> <varname>instance</varname> <varname>new-class</varname></screen>
+<screen><indexterm role="fn"><primary>change-class</primary></indexterm>— Method: <function>change-class</function> (</screen>
+<screen><indexterm role="fn"><primary>change-class</primary></indexterm>— Method: <function>change-class</function> (</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>class-name</primary></indexterm>— Generic: <function>class-name</function> <varname>class</varname></screen>
+<screen><indexterm role="fn"><primary>class-name</primary></indexterm>— Method: <function>class-name</function> (</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>(setf class-name)</primary></indexterm>— Generic: <function>(setf class-name)</function> <varname>new-value</varname> <varname>class</varname></screen>
+<screen><indexterm role="fn"><primary>(setf class-name)</primary></indexterm>— Method: <function>(setf class-name)</function> <varname>new-value (class class)</varname></screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>class-of</primary></indexterm>— Function: <function>class-of</function> <varname>object</varname></screen>
+<para>The function <literal>class-of</literal> returns the class of which the given object is an
+instance. The argument to class-of may be any Common-Lisp object.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>compute-applicable-methods</primary></indexterm>— Function: <function>compute-applicable-methods</function> <varname>generic-function function-arguments</varname></screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>defclass</primary></indexterm>— Macro: <function>defclass</function> <varname>class-name (@{superclass-name@}*)</varname> (<varname>{</varname><varname>slot-specifier</varname><varname>}</varname><varname>*</varname>) [<varname>class-option</varname>]</screen>
+<screen>
+<replaceable>class-name</replaceable> ::= <replaceable>symbol</replaceable>
+<replaceable>superclass-name</replaceable> ::= <replaceable>symbol</replaceable>
+<replaceable>slot-specifier</replaceable> ::= <replaceable>slot-name</replaceable> | (<replaceable>slot-name</replaceable> [<replaceable>slot-option</replaceable>])
+<replaceable>slot-name</replaceable> ::= <replaceable>symbol</replaceable>
+<replaceable>slot-option</replaceable> ::= {:reader <replaceable>reader-function-name</replaceable>}*
+| {:writer <replaceable>writer-function-name</replaceable>}*
+| {:accessor <replaceable>reader-function-name</replaceable>}*
+| {:allocation <replaceable>allocation-type</replaceable>}
+| {:initarg <replaceable>initarg-name</replaceable>}*
+| {:initform <replaceable>form</replaceable>}
+| {:type <replaceable>type-specifier</replaceable>}
+| {:documentation <replaceable>string</replaceable>}
+<replaceable>reader-function-name</replaceable> ::= <replaceable>symbol</replaceable>
+<replaceable>writer-function-name</replaceable> ::= <replaceable>function-name</replaceable>
+<replaceable>function-name</replaceable> ::= <replaceable>symbol</replaceable> |(setf <replaceable>symbol</replaceable>)
+<replaceable>initarg-name</replaceable> ::= <replaceable>symbol</replaceable>
+<replaceable>allocation-type</replaceable> ::= :instance | :class
+<replaceable>class-option</replaceable> ::= (:default-initargs <replaceable>initarg-list</replaceable>)
+| (:documentation <replaceable>string</replaceable>)
+| (:metaclass <replaceable>class-name</replaceable>)
+<replaceable>initarg-list</replaceable> ::= {<replaceable>initarg-name</replaceable> <replaceable>default-initial-value-form</replaceable>}*
+</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>defgeneric</primary></indexterm>— Macro: <function>defgeneric</function> <varname>function-name lambda-list [option | @{method-description@}*]</varname></screen>
+<screen>
+<replaceable>function-name</replaceable> ::= <replaceable>symbol</replaceable> | (setf <replaceable>symbol</replaceable>)
+<replaceable>lambda-list</replaceable> ::= ({<replaceable>var</replaceable>}*
+[&optional {<replaceable>var</replaceable> | (<replaceable>var</replaceable>)}*]
+[&rest <replaceable>var</replaceable>]
+[&key {<replaceable>keyword-parameter</replaceable>}* [&allow-other-keys]])
+<replaceable>keyword-parameter</replaceable> ::= <replaceable>var</replaceable> | ( {<replaceable>var</replaceable> | (<replaceable>keywordvar</replaceable> )})
+<replaceable>option</replaceable> ::= (:argument-precedence-order {<replaceable>parameter-name</replaceable>}+)
+| (declare {<replaceable>declaration</replaceable>}+)
+| (:documentation <replaceable>string</replaceable>)
+| (:method-combination symbol {<replaceable>arg</replaceable>}*)
+| (:generic-function-class <replaceable>class-name</replaceable>)
+| (:method-class <replaceable>class-name</replaceable>)
+<replaceable>method-description</replaceable> ::=
+(:method {<replaceable>method-qualifier</replaceable>}* <replaceable>specialized-lambda-list</replaceable>
+[{<replaceable>declaration</replaceable>}* | <replaceable>documentation</replaceable>]
+{<replaceable>form</replaceable>}*)
+<replaceable>method-qualifier</replaceable> ::= <replaceable>non-nil-atom</replaceable>
+<replaceable>specialized-lambda-list</replaceable> ::= ({<replaceable>var</replaceable> | (<replaceable>var</replaceable> <replaceable>parameter-specializer-name</replaceable>)}*
+[&optional {<replaceable>var</replaceable> | (<replaceable>var</replaceable> [<replaceable>initform</replaceable> [<replaceable>supplied-p-parameter</replaceable>]])}*]
+[&rest <replaceable>var</replaceable>]
+[&key {<replaceable>specialized-keyword-parameter</replaceable>}* [&allow-other-keys]])
+[&aux {<replaceable>var</replaceable> | (<replaceable>var</replaceable> [<replaceable>initform</replaceable>])}*] )
+<replaceable>specialized-keyword-parameter</replaceable> ::= <replaceable>var</replaceable>
+| {({<replaceable>var</replaceable> | (<replaceable>keywordvar</replaceable>)} [<replaceable>initform</replaceable> [<replaceable>supplied-p-parameter</replaceable>]])}*
+<replaceable>parameter-specializer-name</replaceable> ::= <replaceable>symbol</replaceable> | (eql <replaceable>eql-specializer-form</replaceable>)
+</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>define-method-combination</primary></indexterm>— Macro: <function>define-method-combination</function> <varname>name [short-form-option]</varname></screen>
+<screen><indexterm role="fn"><primary>define-method-combination</primary></indexterm>— Macro: <function>define-method-combination</function> <varname>name lambda-list (@{method-group-specifier@}*) [(:arguments . lambda-list)] [(:generic-function generic-fn-symbol)] [@{declaration@}* | doc-string] @{form@}*</varname></screen>
+<screen>
+<replaceable>short-form-option</replaceable> ::= :documentation <replaceable>string</replaceable>
+| :identity-with-one-argument <replaceable>boolean</replaceable>
+| :operator <replaceable>operator</replaceable>
+<replaceable>method-group-specifier</replaceable> ::= (<replaceable>variable</replaceable> {<replaceable>qualifier-pattern</replaceable>}+ | <replaceable>predicate</replaceable>
+[<replaceable>long-form-option</replaceable>])
+<replaceable>long-form-option</replaceable> ::= :description <replaceable>format-string</replaceable>
+| :order <replaceable>order</replaceable>
+| :required <replaceable>boolean</replaceable>
+</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>defmethod</primary></indexterm>— Macro: <function>defmethod</function> <varname>function-name @{method-qualifier@}+ specialized-lambda-list [@{declaration@}* | doc-string] @{form@}*</varname></screen>
+<screen>
+<replaceable>function-name</replaceable> ::= <replaceable>symbol</replaceable> | (setf <replaceable>symbol</replaceable>)
+<replaceable>method-qualifier</replaceable> ::= <replaceable>non-nil-atom</replaceable>
+<replaceable>parameter-specializer-name</replaceable> ::= <replaceable>symbol</replaceable> | (eql <replaceable>eql-specializer-form</replaceable> )
+</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>documentation</primary></indexterm>— Generic: <function>documentation</function> <varname>x</varname> <varname>&optional</varname> <varname>doc-type</varname></screen>
+<screen><indexterm role="fn"><primary>documentation</primary></indexterm>— Method: <function>documentation</function> (</screen>
+<screen><indexterm role="fn"><primary>documentation</primary></indexterm>— Method: <function>documentation</function> (</screen>
+<screen><indexterm role="fn"><primary>documentation</primary></indexterm>— Method: <function>documentation</function> (</screen>
+<screen><indexterm role="fn"><primary>doumentation</primary></indexterm>— Method: <function>doumentation</function> (</screen>
+<screen><indexterm role="fn"><primary>documentation</primary></indexterm>— Method: <function>documentation</function> (</screen>
+<screen><indexterm role="fn"><primary>documentation</primary></indexterm>— Method: <function>documentation</function> (</screen>
+<screen><indexterm role="fn"><primary>documentation</primary></indexterm>— Method: <function>documentation</function> (</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>(setf documentation)</primary></indexterm>— Generic: <function>(setf documentation)</function> <varname>new-value</varname> <varname>x</varname> <varname>&optional</varname> <varname>doc-type</varname></screen>
+<screen><indexterm role="fn"><primary>(setf documentation)</primary></indexterm>— Method: <function>(setf documentation)</function> <varname>new-value (method standard-method) @optional{} doc-type</varname></screen>
+<screen><indexterm role="fn"><primary>(setf documentation)</primary></indexterm>— Method: <function>(setf documentation)</function> <varname>new-value (class standard-class) @optional{} doc-type</varname></screen>
+<screen><indexterm role="fn"><primary>(setf documentation)</primary></indexterm>— Method: <function>(setf documentation)</function> <varname>new-value (method-combination method-combination)</varname></screen>
+<screen><indexterm role="fn"><primary>(setf documentation)</primary></indexterm>— Method: <function>(setf documentation)</function> <varname>new-value (slot-description standard-slot-description) @optional{} doc-type</varname></screen>
+<screen><indexterm role="fn"><primary>(setf documentation)</primary></indexterm>— Method: <function>(setf documentation)</function> <varname>new-value (symbol symbol) @optional{} doc-type</varname></screen>
+<screen><indexterm role="fn"><primary>(setf documentation)</primary></indexterm>— Method: <function>(setf documentation)</function> <varname>new-value (list list) @optional{} doc-type</varname></screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>ensure-generic-function</primary></indexterm>— Function: <function>ensure-generic-function</function> <varname>{</varname><varname>function-name</varname> <varname>&key</varname> <varname>lambda-list</varname> <varname>&key</varname> <varname>:argument-precedence-order</varname> <varname>:declare</varname> <varname>:documentation</varname> <varname>:generic-function-class|ekeys</varname><varname>:method-combination :method-class :environment</varname><varname>}</varname></screen>
+<screen>
+function-name ::= symbol | (setf symbol)
+</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>find-class</primary></indexterm>— Function: <function>find-class</function> <varname>symbol @optional{} errorp environment</varname></screen>
+<para>The function find-class returns the class object named by the given symbol in the given environment.
+The first argument to find-class is a symbol.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>find-method</primary></indexterm>— Generic: <function>find-method</function> <varname>generic-function</varname> <varname>method-qualifiers</varname> <varname>specializers</varname> <varname>&optional</varname> <varname>errorp</varname></screen>
+<screen><indexterm role="fn"><primary>find-method</primary></indexterm>— Method: <function>find-method</function> (</screen>
+<para>method-qualifiers specializers &optional errorp</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>function-keywords</primary></indexterm>— Generic: <function>function-keywords</function> <varname>method</varname></screen>
+<screen><indexterm role="fn"><primary>function-keywords</primary></indexterm>— Method: <function>function-keywords</function> (</screen>
+</blockquote>
+<para>The generic function function-keywords is used to return the keyword parameter specifiers for a given method.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>generic-function</primary></indexterm>— Macro: <function>generic-function</function> <varname>{</varname><varname>lambda-list</varname> <varname>\mchoice</varname><varname>option | @{method-description@}*</varname><varname>}</varname></screen>
+<screen>
+option ::= (:argument-precedence-order {parameter-name}+)
+| (declare {declaration}+)
+| (:documentation string)
+| (:method-combination symbol {arg}*)
+| (:generic-function-class class-name)
+| (:method-class class-name)
+method-description ::= (:method {method-qualifier}*
+specialized-lambda-list
+{declaration | <replaceable>documentation</replaceable>}*
+{form}*)
+</screen>
+<para>The <literal>generic-function</literal> macro creates an anonymous generic function. The
+generic function is created with the set of methods specified by its method
+descriptions. The <replaceable>option</replaceable>, <replaceable>method-qualifier</replaceable>, and
+<replaceable>specialized-lambda-list</replaceable> arguments are the same as for <literal>defgeneric</literal>.
+The generic function object is returned as the result. If no method
+descriptions are specified, an anonymous generic function with no methods is
+created. See defgeneric, generic-flet,
+generic-labels, defmethod.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>initialize-instance</primary></indexterm>— Generic: <function>initialize-instance</function> <varname>instance</varname> <varname>&rest</varname> <varname>initargs</varname></screen>
+<screen><indexterm role="fn"><primary>initialize-instance</primary></indexterm>— Method: <function>initialize-instance</function> (</screen>
+<para>The generic function <literal>initialize-instance</literal> is called by
+<literal>make-instance</literal> to initialize a newly created instance. The generic
+function <literal>initialize-instance</literal> is called with the new instance and the
+defaulted initialization arguments.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>invalid-method-error</primary></indexterm>— Function: <function>invalid-method-error</function> <varname>method format-string @rest{} args</varname></screen>
+<para>The function <literal>invalid-method-error</literal> is used to signal an error when there
+is an applicable method whose qualifiers are not valid for the method
+combination type. The error message is constructed by using a format string
+and any arguments to it. Because an implementation may need to add additional
+contextual information to the error message, invalid-method-error should be
+called only within the dynamic extent of a method combination function. The
+function invalid-method-error is called automatically when a method fails to
+satisfy every qualifier pattern and predicate in a define-method-combination
+form. A method combination function that imposes additional restrictions
+should call invalid-method-error explicitly if it encounters a method it cannot
+accept.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>make-instance</primary></indexterm>— Generic: <function>make-instance</function> <varname>class</varname> <varname>&rest</varname><varname> initargs</varname></screen>
+<screen><indexterm role="fn"><primary>make-instance</primary></indexterm>— Method: <function>make-instance</function> (</screen>
+<screen><indexterm role="fn"><primary>make-instance</primary></indexterm>— Method: <function>make-instance</function> (</screen>
+<para>The generic function make-instance creates and returns a new instance of the
+given class. The generic function make-instance may be used as described in
+section 1.9. The class argument is a class object or a symbol that names a
+class. The remaining arguments form a list of alternating initialization
+argument names and values. If the second of the above methods is selected,
+that method invokes make-instance on the arguments (find-class class) and
+initargs. The initialization arguments are checked within make-instance (see
+section 1.9). The new instance is returned.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>make-instances-obsolete</primary></indexterm>— Generic: <function>make-instances-obsolete</function> <varname>class</varname></screen>
+<screen><indexterm role="fn"><primary>make-instances-obsolete</primary></indexterm>— Method: <function>make-instances-obsolete</function> (</screen>
+<screen><indexterm role="fn"><primary>make-instances-obsolete</primary></indexterm>— Method: <function>make-instances-obsolete</function> (</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>method-combination-error</primary></indexterm>— Function: <function>method-combination-error</function> <varname>format-string @rest{} args</varname></screen>
+<para>The function method-combination-error is used to signal an error in method
+combination. The error message is constructed by using a format string and any
+arguments to it. Because an implementation may need to add additional
+contextual information to the error message, method-combination-error should be
+called only within the dynamic extent of a method combination function. The
+format-string argument is a control string that can be given to format, and
+args are any arguments required by that string.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>method-qualifiers</primary></indexterm>— Generic: <function>method-qualifiers</function> <varname>method</varname></screen>
+<screen><indexterm role="fn"><primary>method-qualifiers</primary></indexterm>— Method: <function>method-qualifiers</function> (</screen>
+<para>The generic function method-qualifiers returns a list of the qualifiers
+of the given method.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>next-method-p</primary></indexterm>— Function: <function>next-method-p</function> <varname></varname></screen>
+<para>The locally defined function next-method-p can be used within the body of a
+method defined by a method-defining form to determine whether a next method
+exists.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>no-applicable-method</primary></indexterm>— Generic: <function>no-applicable-method</function> <varname>generic-function</varname> <varname>&rest</varname> <varname>function-arguments</varname></screen>
+<screen><indexterm role="fn"><primary>no-applicable-method</primary></indexterm>— Method: <function>no-applicable-method</function> (</screen>
+<para>The generic function no-applicable-method is called when a generic function of
+the class standard-generic-function is invoked and no method on that generic
+function is applicable. The default method signals an error.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>no-next-method</primary></indexterm>— Generic: <function>no-next-method</function> <varname>generic-function</varname> <varname>method</varname> <varname>&rest</varname> <varname>args</varname></screen>
+<screen><indexterm role="fn"><primary>no-next-method</primary></indexterm>— Method: <function>no-next-method</function> (</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>print-object</primary></indexterm>— Generic: <function>print-object</function> <varname>object</varname> <varname>stream</varname></screen>
+<screen><indexterm role="fn"><primary>print-object</primary></indexterm>— Method: <function>print-object</function> (</screen>
+<para>The generic function print-object writes the printed representation of an
+object to a stream. The function print-object is called by the print system;
+it should not be called by the user.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>reinitialize-instance</primary></indexterm>— Generic: <function>reinitialize-instance</function> <varname>instance</varname> <varname>&rest</varname> <varname>initargs</varname></screen>
+<screen><indexterm role="fn"><primary>reinitialize-instance</primary></indexterm>— Method: <function>reinitialize-instance</function> (</screen>
+<para>The generic function reinitialize-instance can be used to change the
+values of local slots according to initialization arguments. This
+generic function is called by the Meta-Object Protocol. It can also be
+called by users.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>remove-method</primary></indexterm>— Generic: <function>remove-method</function> <varname>generic-function</varname> <varname>method</varname></screen>
+<screen><indexterm role="fn"><primary>remove-method</primary></indexterm>— Method: <function>remove-method</function> (</screen>
+<para>The generic function remove-method removes a method from a generic function.
+It destructively modifies the specified generic function and returns the
+modified generic function as its result.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>shared-initialize</primary></indexterm>— Generic: <function>shared-initialize</function> <varname>instance slot-names &rest initargs</varname></screen>
+<screen><indexterm role="fn"><primary>shared-initialize</primary></indexterm>— Method: <function>shared-initialize</function> (</screen>
+<para>The generic function shared-initialize is used to fill the slots of an instance
+using initialization arguments and :initform forms. It is called when an
+instance is created, when an instance is re-initialized, when an instance is
+updated to conform to a redefined class, and when an instance is updated to
+conform to a different class. The generic function <literal>shared-initialize</literal> is
+called by the system-supplied primary method for <literal>initialize-instance</literal>,
+<literal>reinitialize-instance</literal>, <literal>update-instance-for-redefined-class</literal>, and
+<literal>update-instance-for-different-class</literal>.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>slot-boundp</primary></indexterm>— Function: <function>slot-boundp</function> <varname>instance slot-name</varname></screen>
+<para>The function slot-boundp tests whether a specific slot in an instance is bound.
+The arguments are the instance and the name of the slot.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>slot-exists-p</primary></indexterm>— Function: <function>slot-exists-p</function> <varname>object slot-name</varname></screen>
+<para>The function slot-exists-p tests whether the specified object has a slot of the
+given name. The object argument is any object. The slot-name argument is a
+symbol.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>slot-makunbound</primary></indexterm>— Function: <function>slot-makunbound</function> <varname>instance slot-name</varname></screen>
+<para>The function slot-makunbound restores a slot in an instance to the unbound
+state. The arguments to slot-makunbound are the instance and the name of the
+slot.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>slot-missing</primary></indexterm>— Generic: <function>slot-missing</function> <varname>class</varname> <varname>object</varname> <varname>slot-name</varname> <varname>operation</varname> <varname>&optional</varname> <varname>new-value</varname></screen>
+<screen><indexterm role="fn"><primary>slot-missing</primary></indexterm>— Method: <function>slot-missing</function> (</screen>
+<para>The generic function slot-missing is invoked when an attempt is made to access
+a slot in an object whose metaclass is standard-class and the name of the slot
+provided is not a name of a slot in that class. The default method signals an
+error.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>slot-unbound</primary></indexterm>— Generic: <function>slot-unbound</function> <varname>class</varname> <varname>instance</varname> <varname>slot-name</varname></screen>
+<screen><indexterm role="fn"><primary>slot-unbound</primary></indexterm>— Method: <function>slot-unbound</function> (</screen>
+<para>The generic function slot-unbound is called when an unbound slot is read in an
+instance whose metaclass is standard-class. The default method signals an
+error.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>slot-value</primary></indexterm>— Function: <function>slot-value</function> <varname>object slot-name</varname></screen>
+<para>The function slot-value returns the value contained in the slot slot-name of
+the given object. If there is no slot with that name, slot-missing is called.
+If the slot is unbound, slot-unbound is called. The macro setf can be used
+with slot-value to change the value of a slot.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>update-instance-for-different-class</primary></indexterm>— Generic: <function>update-instance-for-different-class</function> <varname>previous</varname> <varname>current</varname> <varname>&rest</varname> <varname>initargs</varname></screen>
+<screen><indexterm role="fn"><primary>update-instance-for-different-class</primary></indexterm>— Method: <function>update-instance-for-different-class</function> (</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>update-instance-for-redefined-class</primary></indexterm>— Generic: <function>update-instance-for-redefined-class</function> <varname>instance</varname> <varname>added-slots</varname> <varname>discarded-slots</varname> <varname>property-list</varname> <varname>&rest</varname> <varname>initargs</varname></screen>
+<screen><indexterm role="fn"><primary>update-instance-for-redefined-class</primary></indexterm>— Method: <function>update-instance-for-redefined-class</function> (</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>with-accessors</primary></indexterm>— Macro: <function>with-accessors</function> (</screen>
+<para>The macro with-accessors creates a lexical environment in which specified slots
+are lexically available through their accessors as if they were variables. The
+macro with-accessors invokes the appropriate accessors to access the specified
+slots. Both setf and setq can be used to set the value of the slot. The
+result returned is that obtained by executing the forms specified by the body
+argument.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>with-slots</primary></indexterm>— Macro: <function>with-slots</function> (</screen>
+<screen>
+<replaceable>slot-entry</replaceable> ::= <replaceable>slot-name</replaceable> | (<replaceable>variable-name</replaceable> <replaceable>slot-name</replaceable>)
+</screen>
+<para>The macro <literal>with-slots</literal> creates a lexical context for referring to
+specified slots as though they were variables. Within such a context the value
+of the slot can be specified by using its slot name, as if it were a lexically
+bound variable. Both <literal>setf</literal> and <literal>setq</literal> can be used to set the value
+of the slot.</para>
+</blockquote>
+</chapter>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+--></book>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter label="7" xml:id="The-compiler">
+<title>The Compiler</title>
+<para>The &ECL; compiler translates a Lisp program stored in a source file into a C
+program, invokes the C compiler to compile the C program, and then generates an
+object file, called <emphasis>fasl file</emphasis> (or <emphasis>o-file</emphasis> because of the actual
+filetype). The compiled program in a fasl file is loaded by the function
+<literal>load</literal>.</para>
+<para>Ordinarily, the object program generated by the &ECL; compiler scarcely does
+runtime error-checking for runtime efficiency. In addition, Lisp functions in
+the same source file are linked together and some system functions are
+open-coded in-line. To control runtime error checking, supply appropriate
+<literal>optimize</literal> declarations (see Section 7.1).</para>
+<para>The &ECL; compiler processes the <literal>eval-when</literal> special form exactly as
+specified in &Steele84; (see Section 5.3.3 of &Steele84;).</para>
+<para>The &ECL; compiler is invoked by the functions <literal>compile-file</literal>,
+<literal>compile</literal>, and <literal>disassemble</literal> described below. In addition, the
+&ECL; compiler may be invoked directly by the Shell commands <literal>ecl</literal>.
+This command requires the file name of the source file as its
+argument. <literal>ecl</literal> simply adds <literal>.lsp</literal> to the file name argument to
+obtain the full name of the source file.</para>
+<para><screen>
+$ ecl <replaceable>filename</replaceable>
+</screen></para>
+<para role="continues">has the same effect as the compiler invocation <literal>(compile-file
+<replaceable>filename</replaceable>)</literal> from within &ECL;, and</para>
+<para><screen>
+$ ecl -C <replaceable>filename</replaceable>
+</screen></para>
+<para>has the same effects as <literal>(compile-file <replaceable>filename</replaceable>
+:c-file t :h-file t :data-file t)</literal>.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>compile-file</primary></indexterm>— Function: <function>compile-file</function> <varname>pathname &key :output-file :verbose :print :c-file :h-file :data-file</varname></screen>
+<para><literal>compile-file</literal> compiles the Lisp program stored in the file specified by
+<replaceable>pathname</replaceable>, and generates a binary file. If <replaceable>:verbose</replaceable> is true, a
+message indicating what file is being compiled is printed. If <replaceable>:print</replaceable>
+is true, information about top-level forms in the file being compiled is
+printed. <literal>compile-file</literal> generates the following temporary files:</para>
+<informaltable>
+<tgroup cols="2">
+<colspec colwidth="16*"></colspec>
+<colspec colwidth="43*"></colspec>
+<tbody>
+<row>
+<entry><emphasis role="bold">Temporary File</emphasis></entry>
+<entry><emphasis role="bold">Contents</emphasis></entry>
+</row>
+<row>
+<entry><replaceable>c-file</replaceable></entry>
+<entry>C version of the Lisp program</entry>
+</row>
+<row>
+<entry><replaceable>h-file</replaceable></entry>
+<entry>The include file referenced in the c-file</entry>
+</row>
+<row>
+<entry><replaceable>data-file</replaceable></entry>
+<entry>The Lisp data to be used at load time</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>If files of these names already exist, the old files will be deleted first.
+Usually, these intermediate files are automatically deleted after execution of
+<literal>compile-file</literal>.</para>
+<para>The input-file is determined in the usual manner (see Section 2.9), except
+that, if the filetype is not specified, then the default filetype <literal>.lsp</literal>
+will be used. The keyword parameter <literal>:output-file</literal> defines the default
+directory and the default name to be applied to the output files (i.e., the
+fasl file and the temporary files). <replaceable>:output-file</replaceable> itself defaults to
+<replaceable>input-pathname</replaceable>. That is, if <replaceable>:output-file</replaceable> is not supplied, then the
+directory and the name of the input file will be used as the default directory
+and the default name for the output files. The file types of the output files
+are fixed as follows.</para>
+<informaltable>
+<tgroup cols="2">
+<colspec colwidth="46*"></colspec>
+<colspec colwidth="43*"></colspec>
+<tbody>
+<row>
+<entry><emphasis role="bold">Output File</emphasis></entry>
+<entry><emphasis role="bold">Filetype</emphasis></entry>
+</row>
+<row>
+<entry>fasl file</entry>
+<entry><literal>.o</literal></entry>
+</row>
+<row>
+<entry>c-file</entry>
+<entry><literal>.c</literal></entry>
+</row>
+<row>
+<entry>h-file</entry>
+<entry><literal>.h</literal></entry>
+</row>
+<row>
+<entry>data-file</entry>
+<entry><literal>.data</literal></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>Each output file can be specified by the corresponding keyword parameter.
+If the value of the keyword parameter is (), then the output file will be
+deleted after execution of <literal>compile-file</literal>. If the value of the
+keyword parameter is <replaceable>T</replaceable>, then the output file will be left in the
+default directory under the default name. Otherwise, the output file will
+be left in the directory under the name specified by the keyword parameter.
+The default value of <replaceable>:output-file</replaceable> is <replaceable>T</replaceable>, and the default values
+of <replaceable>:c-file</replaceable>, <replaceable>::h-file</replaceable>, and <replaceable>:data-file</replaceable> are all ().</para>
+<variablelist>
+<varlistentry>
+<term><literal>(compile-file 'foo)</literal></term>
+<listitem>
+<para>The source file is <literal>FOO.lsp</literal> and the fasl file is <literal>FOO.o</literal>
+both in the current directory.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>(compile-file 'foo.lish)</literal></term>
+<listitem>
+<para>The source file is <literal>FOO.LISH</literal> and the fasl file is <literal>FOO.o</literal>'.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>(compile-file "/usr/mas/foo" :output-file "/usr/tai/baa")</literal></term>
+<listitem>
+<para>The source file is <literal>foo.lsp</literal> in the directory <filename>/usr/mas</filename>, and the
+fasl file is <literal>baa.o</literal> in the directory <filename>/usr/tai</filename>.</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>compile</primary></indexterm>— Function: <function>compile</function> <varname>name code &optional definition</varname></screen>
+<para>If <replaceable>definition</replaceable> is not supplied, <replaceable>name</replaceable> should be the name of a
+not-yet-compiled function. In this case, compile compiles the function,
+replaces the previous definition of <replaceable>name</replaceable> with the compiled
+function,<emphasis>and</emphasis> returns <replaceable>name</replaceable>. If <replaceable>definition</replaceable> is supplied, it
+should be a lambda-expression to be compiled and <replaceable>name</replaceable> should be a symbol.
+If <replaceable>name</replaceable> is a non-() symbol, then compile installs the compiled
+function as the function definition of <replaceable>name</replaceable> and returns <replaceable>name</replaceable>. If
+<replaceable>name</replaceable> is (), then compile simply returns the compiled function.</para>
+<para>The &ECL; compiler is essentially a file compiler, and forms to be
+compiled are supposed to be stored in a file. Thus compile actually
+creates a source file which contains the form designated by the
+arguments. Then compile calls <literal>compile-file</literal> to get a fasl file,
+which is then loaded into &ECL;. The source file and the fasl file
+are given the names <filename>gazonk.lsp</filename> and <filename>gazonk.fasl</filename>,
+respectively. These files are not deleted automatically after the
+execution of <literal>compile</literal>.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>disassemble</primary></indexterm>— Function: <function>disassemble</function> <varname>&optional thing &key :h-file :data-file</varname></screen>
+<para>This function does not actually disassemble. It always calls the &ECL;
+compiler and prints the contents of the c-file, i.e., the C-language code,
+generated by the &ECL; compiler. If <replaceable>thing</replaceable> is not supplied, or if it is
+(), then the previously compiled form by disassemble will be compiled
+again. If <replaceable>thing</replaceable> is a symbol other than (), then it must be the name
+of a not-yet-compiled function, whose definition is to be compiled. In this
+case, it is an error if the name is associated with a special form or a macro.
+If <replaceable>thing</replaceable> is a lambda-expression <literal>(lambda <replaceable>lambda-list .
+body</replaceable>)</literal>, then <literal>disassemble</literal> first creates a function definition
+<literal>(defun gazonk <replaceable>lambda-list . body</replaceable>)</literal> and this definition is
+compiled. (The function name <literal>gazonk</literal> has no special meanings. Indeed,
+the displayed code is essentially independent of the function name.)
+Otherwise, <replaceable>thing</replaceable> itself will be compiled as a top-level form. In any
+case, <literal>disassemble</literal> does not install the compiled function.
+<literal>disassemble</literal> returns no value.</para>
+<para>No intermediate h-file is created if the keyword parameter <literal>:h-file</literal> is
+() or if <replaceable>:h-file</replaceable> is not supplied. Otherwise, an intermediate h-file
+is created under the name specified by <replaceable>:h-file</replaceable>. Similarly, the
+intermediate data-file is specified by the keyword parameter <replaceable>:data-file</replaceable>.</para>
+</blockquote>
+</chapter>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+--></book>
--- /dev/null
+ <legalnotice xml:id="Copyright">
+ <title>Copyright</title>
+<synopsis>
+---- BEGINNING OF COPYRIGHT FOR THE ECL CORE ENVIRONMENT ------------
+
+ Copyright (c) 2000, Juan Jose Garcia Ripoll
+ Copyright (c) 1990, 1991, 1993 Giuseppe Attardi
+ Copyright (c) 1984 Taiichi Yuasa and Masami Hagiya
+ All Rights Reserved
+
+ ECL is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version; see file 'Copying'.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ PLEASE NOTE THAT:
+
+ This license covers all of the ECL program except for the files
+ src/lsp/loop2.lsp ; Symbolic's LOOP macro
+ src/lsp/pprint.lsp ; CMUCL's pretty printer
+ src/lsp/format.lsp ; CMUCL's format
+ and the directories
+ contrib/ ; User contributed extensions
+ src/clx/ ; portable CLX library from Telent
+ Look the precise copyright of these extensions in the corresponding
+ files.
+
+ Report bugs, comments, suggestions to the ecl mailing list:
+ ecls-list@lists.sourceforge.net.
+
+---- END OF COPYRIGHT FOR THE ECL CORE ENVIRONMENT ------------------
+</synopsis>
+ </legalnotice>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="Declarations">
+<title>Declarations</title>
+<para>&ECL; supports all kinds of declarations described in the
+&Steele84;. Any valid declaration will affect the &ECL; environment
+in some way or another, although information obtained by declarations, other
+than special declarations, is mainly used by the &ECL; compiler.</para>
+<para>As described in &Steele84;, Common-Lisp declarations are divided into two
+classes: <replaceable>proclamations</replaceable> and others. A proclamation is a global
+declaration given by the function <literal>proclaim</literal>, the top-level <emphasis>macro</emphasis>
+<literal>defvar</literal>, or the top-level macro <literal>defparameter</literal>. Once given, a
+proclamation remains effective during the &ECL; session unless it is shadowed
+by a local declaration or is canceled by another proclamation. Any other
+declaration is a <emphasis>local declaration</emphasis> and is given only by the special form
+<literal>declare</literal>. A local declaration remains in effect only within the body of
+the construct that surrounds the declaration.</para>
+<para>In the following nonsensical example borrowed from Chapter 9 of
+&Steele84;,</para>
+<programlisting>
+(defun nonsense (k x z)
+(foo z x)
+(let ((j (foo k x))
+(x (* k k)))
+(declare (inline foo) (special x z))
+(foo x j z)))
+</programlisting>
+<para role="continues">the <literal>inline</literal> and the special declarations both remain in effect within the
+surrounding <literal>let</literal> form. In this case, we say that the <literal>let</literal> form is
+the <emphasis>surrounding construct</emphasis> of these declarations.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>the</primary></indexterm>— Special Form: <function>the</function> <varname>value-type form</varname></screen>
+<para>The &ECL; interpreter does actually check whether the value of the
+<emphasis>form</emphasis> conforms to the data type specified by <emphasis>value-type</emphasis> and
+signals an error if the value does not. The type checking is performed by
+the function <literal>typep</literal>. For example,</para>
+</blockquote>
+<programlisting>(the fixnum (foo))
+</programlisting>
+<para role="continues">is equivalent to</para>
+<programlisting>
+(let ((values (multiple-value-list (foo))))
+(cond ((endp values) (error ``Too few return values."))
+((not (endp (cdr values)))
+(error ``Too many return values."))
+((typep (car values) 'fixnum) (car values))
+(t (error ``~s is not of type fixnum." (car values)))))
+</programlisting>
+<para>On the other hand, the &ECL; compiler uses the special form to
+obtain type information for compiled code optimization. No code for
+runtime type-checking is embedded in the compiled code.</para>
+
+<section xml:id="Declaration-specifiers">
+<title>Declaration Specifiers</title>
+<para>&ECL; recognizes all declaration specifiers defined in &Steele84;.
+The syntax of each such declaration specifier is exactly the same as defined in
+&Steele84;. In addition, &ECL; recognizes the <literal>object</literal>
+declaration specifier which is specific to &ECL;.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>special</primary></indexterm>— Declaration: <function>special</function> <varname>{</varname><varname>variable-name</varname><varname>}</varname><varname>*</varname></screen>
+<para>The interpreter and the compiler of &ECL; both treat special declarations
+exactly as described in &Steele84;.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>type</primary></indexterm>— Declaration: <function>type</function> <varname>type</varname> <varname>{</varname><varname>variable-name</varname><varname>}</varname><varname>*</varname></screen>
+<para>A <literal>type</literal> proclamation <literal>(type
+<replaceable>type var1 var2</replaceable> ...)</literal></para>
+<para>specifies
+that the dynamic values of the named variables are of the type <emphasis>type</emphasis>. A
+local <literal>type</literal> declaration specifies that the variables mentioned are bound
+by the surrounding construct and have values of the type <emphasis>type</emphasis> during
+execution of the surrounding construct. The compiler issues a warning if one
+of the named variables is not bound by the surrounding construct. The
+information given by <literal>type</literal> declarations is used by the compiler to
+optimize the compiled code. The behavior of the compiled code is unpredictable
+if a wrong <literal>type</literal> declaration is supplied. The compiler detects certain
+wrong <literal>type</literal> declarations at compile time.</para>
+</blockquote>
+<para>For example,<screen>
+>(defun foo (x y)
+(declare (fixnum x) (character y))
+(setq x y)
+...))
+foo
+
+>(compile 'foo)
+
+; (defun foo ...) is being compiled.
+;; Warning: Type mismatches between x and y.
+</screen></para>
+<para>See Section 7.3 for further information on <literal>type</literal> declarations.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>type</primary></indexterm>— Declaration: <function>type</function> <varname>{</varname><varname>variable-name</varname><varname>}</varname><varname>*</varname></screen>
+<para>(<replaceable>type var1 var2</replaceable> ...) is equivalent to <literal>(type <replaceable>type var1 var2</replaceable>
+...)</literal>, provided that <replaceable>type</replaceable> is one of the symbols in Table 4-1 of
+&Steele84;, other than <literal>function</literal>. Declaration specifications
+that begin with <literal>function</literal> are regarded as <literal>function</literal> declarations
+(see below).</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>function</primary></indexterm>— Declaration: <function>function</function> <varname>function-name</varname> <varname>argument-types</varname> <varname>.</varname> <varname>return-types</varname></screen>
+<para>A <literal>function</literal> declaration is used to obtain type information for function
+call forms. That is, a <literal>function</literal> declaration specifies the argument and
+the return types of each form that calls the named function.</para>
+</blockquote>
+<programlisting>(defun foo ()
+(declare (function bar (character) fixnum))
+(+ (bar (atcholi1)) (bar (atcholi2))))
+</programlisting>
+<para>In this example, the <literal>function</literal> declaration specifies that the two
+functions <literal>atcholi1</literal> and <literal>atcholi2</literal> both return character objects
+when called within the body of <literal>foo</literal>, and that the function bar returns
+fixnum objects when called within the body of <literal>foo</literal>. The type information
+given by function declarations is used by the compiler to optimize the compiled
+code. The behavior of the compiled code is unpredictable if a wrong
+<literal>function</literal> declaration is supplied. The compiler detects certain wrong
+<literal>function</literal> declarations at compile time.</para>
+<para>For example,</para>
+<para><screen>
+>(defun foo (x)
+(declare (fixnum x)
+(function bar (character) fixnum))
+(bar x))
+foo
+
+>(compile 'foo)
+
+; (defun foo ...) is being compiled.
+;; Warning: The type of the form x is not character.
+</screen></para>
+<para>However, the compiler does not check the number of arguments, and thus, the
+following function definition will be compiled successfully without any
+warnings.</para>
+<programlisting>(defun foo ()
+(declare (function bar (character character) fixnum))
+(+ (bar (atcholi1)) (bar (atcholi2) (atcholi3) (atcholi4))))
+</programlisting>
+<para>For this definition, the compiler assumes that the three functions
+<literal>atcholi1</literal>, <literal>atcholi2</literal>, and <literal>atcholi3</literal> will return fixnum
+objects. The return type of <literal>atcholi4</literal> is unknown at compile time.</para>
+<para>The complete syntax of a function declaration is:</para>
+<screen>(function function-name
+({type}* [{&optional | &rest | &key} {thing}*])
+{(values {type}* ) | {type}*}
+)
+</screen>
+<para>Although &optional, &rest, and &key markers may appear in the list of
+argument types, only those <replaceable>types</replaceable> are recognized that appear before any
+such markers and the rest of the list is simply ignored. Note that functions
+with &optional, &rest, or &key parameters may still be declared by
+<literal>function</literal> declarations because of the use of <literal>function</literal> declarations
+mentioned above.</para>
+<para>The <literal>values</literal> construct in the specification of return types is almost
+useless: <literal>(function <replaceable>function-name argument-types</replaceable> (<replaceable>values</replaceable>
+<replaceable>type1 type2</replaceable> …))</literal> is equivalent to <literal>(function
+<replaceable>function-name argment-types type1 type2</replaceable> …)</literal>.</para>
+<para>See Section 7.3 for further information on <literal>function</literal> declarations.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>ftype</primary></indexterm>— Declaration: <function>ftype</function> <varname>function-type</varname> <varname>{</varname><varname>function-name</varname><varname>}</varname><varname>*</varname></screen>
+<para><replaceable>function-type</replaceable> must be a list whose first element is the symbol
+<literal>function</literal>. <literal>(ftype (function . <replaceable>rest</replaceable>) <replaceable>function-name-1</replaceable>
+... <replaceable>function-name-n</replaceable>)</literal> is equivalent to <replaceable>n</replaceable> consecutive
+<literal>function</literal> declarations <literal>(function <replaceable>function-name-1</replaceable>
+. <replaceable>rest</replaceable>)</literal> ... <literal>(function <replaceable>function-name-n</replaceable> . <replaceable>rest</replaceable>)</literal>.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>notinline</primary></indexterm>— Declaration: <function>notinline</function> <varname>{</varname><varname>function-name</varname><varname>}</varname><varname>*</varname></screen>
+<para><literal>(notinline <replaceable>function1 function2</replaceable> ...)</literal> specifies that the
+compiler should not compile the named functions in-line. Calls to the
+named functions can be traced and an event (see Section 5.4) is pushed
+on the event stack when any one of the named functions is invoked.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>inline</primary></indexterm>— Declaration: <function>inline</function> <varname>{</varname><varname>function-name</varname><varname>}</varname><varname>*</varname></screen>
+<para>An <literal>inline</literal> proclamation cancels currently effective <literal>notinline</literal>
+proclamations, and a local <literal>inline</literal> declaration locally shadows currently
+effective <literal>notinline</literal> declarations.</para>
+</blockquote>
+<para><screen>
+>(defun foo (x)
+(cons (car x)
+(locally (declare (inline car)) (car x))))
+foo
+>(defun bar (x)
+(cons (car x)
+(locally (declare (inline car)) (car x))))
+foo
+>(proclaim '(notinline car))
+nil
+>(compile 'foo)
+...
+>(proclaim '(inline car))
+nil
+>(compile 'bar)
+...
+</screen></para>
+<para>Usually, primitive functions such as <literal>car</literal> are compiled in-line.
+Therefore, in this example, only the first call to <literal>car</literal> within <literal>foo</literal>
+is compiled not in-line.</para>
+<para>In general, the &ECL; compiler compiles functions in-line whenever possible.
+Thus an <literal>inline</literal> declaration <literal>(inline <replaceable>function1 function2</replaceable> ...)</literal>
+is worthless if none of the named functions have previously been declared to be
+<literal>notinline</literal>.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>ignore</primary></indexterm>— Declaration: <function>ignore</function> <varname>{</varname><varname>variable-name</varname><varname>}</varname><varname>*</varname></screen>
+<para>Usually, the compiler issues a warning if a lexical variable is never referred
+to. <literal>(ignore <replaceable>var1 ... varn</replaceable>)</literal> causes the compiler not to issue a
+warning even if the named variables are never referred to. The compiler issues
+a warning if one of the named variables is not bound by the surrounding
+construct, or if a named variable is actually referred to. <literal>ignore</literal>
+proclamations are simply ignored.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>optimize</primary></indexterm>— Declaration: <function>optimize</function> <varname>{</varname>(<varname>quality</varname> <varname>value</varname>) <varname>|</varname> <varname>quality</varname><varname>}</varname><varname>*</varname></screen>
+<para>&ECL; supports the four <literal>optimize</literal> qualities listed in the
+&Steele84;.</para>
+<para><literal>speed</literal> and <literal>compilation-speed</literal> are used to set up the optimization
+switch of the C language compiler which is invoked to compile the C-language
+code generated by the &ECL; compiler (see Chapter 6). <literal>(optimize (speed
+<replaceable>n</replaceable>))</literal> and <literal>(optimize (compilation-speed <replaceable>m</replaceable>))</literal> are equivalent,
+where <replaceable>n</replaceable> and <replaceable>m</replaceable> are integers between 0 and 3, and <replaceable>m</replaceable> is equal to
+3-<replaceable>n</replaceable>. When a &ECL; session is started, the <literal>speed</literal> quality is set
+to 3. That is, by default, the compiler generates the fastest code in the
+longest compilation time. The <literal>space</literal> quality specifies whether the code
+size is important or not: The compiled code is a little bit larger and faster
+when compiled with the space quality 0, than when compiled with the space
+quality 1, 2, or 3. When a &ECL; session is started, the <literal>space</literal>
+quality is set to 0. The <literal>safety</literal> quality determines how much runtime
+error checking code should be embedded in the compiled code. If the
+<literal>safety</literal> quality is 0, the compiled code scarcely does runtime error
+checking. If the <literal>safety</literal> quality is 1, then the compiled code for a
+function will check the number of arguments to the function at runtime. If the
+<literal>safety</literal> quality is 2 or 3, then the compiled code does full runtime error
+checking. In addition, the highest quality value 3 causes the compiler to
+treat all functions as if they were declared to be <literal>notinline</literal>. When a
+&ECL; session is started, the <literal>safety</literal> quality is set to 0.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>declaration</primary></indexterm>— Declaration: <function>declaration</function> <varname>{</varname><varname>name</varname><varname>}</varname><varname>*</varname></screen>
+<para>A <literal>declaration</literal> declaration is used exactly as specified in the
+&Steele84;.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>object</primary></indexterm>— Declaration: <function>object</function> <varname>{</varname><varname>variable-name</varname><varname>}</varname><varname>*</varname></screen>
+<para>This is the only declaration specifier that is specific to &ECL;.
+<literal>(object <replaceable>var1 ... varn</replaceable>)</literal> affects only variable bindings and
+specifies that the named variables can be allocated in the C stack (see Section
+7.3). The compiler issues a warning if one of the named variables is not bound
+by the surrounding construct. <literal>object</literal> proclamations are simply ignored.</para>
+</blockquote>
+</section>
+
+<section xml:id="Type-specifiers">
+<title>Significant Type Specifiers</title>
+<para>Whenever a declaration is encountered, each type specifier (if any) in the
+declaration is converted to one of the following type specifiers, which are
+collectively called the <emphasis>significant type specifiers</emphasis>.</para>
+<screen><![CDATA[
+|------------ fixnum
+|------------ character
+|------------ short-float
+|------------ long-float
+t --|---- (array t) -------------- (vector t)
+|---- (array fixnum) --------- (vector fixnum)
+|---- (array string-char) --- string
+|---- (array short-float) --- (vector short-float)
+|---- (array long-float) --- (vector long-float)
+|---- (array bit) ----------- bit-vector
+]]></screen>
+<para>Here, the lines indicate subtype relations; the right type is a subtype of the
+left type. For instance, <literal>(vector t)</literal> is a subtype of <literal>(array t)</literal>
+and <replaceable>T</replaceable>, and <literal>(array t)</literal> itself is a subtype of <replaceable>T</replaceable>. However,
+<literal>(array t)</literal> and <literal>(array string-char)</literal> are disjoint types.</para>
+<para>The function <literal>subtypep</literal> is used for the conversion to significant type
+specifiers: If the first value of <literal>(subtypep <replaceable>raw-type type</replaceable>)</literal> is
+<replaceable>T</replaceable> for one of the significant type specifiers <replaceable>type</replaceable>, then the type
+specifier <replaceable>raw-type</replaceable> in the declaration is converted to <replaceable>type</replaceable>. If
+there are more than one such significant type specifiers, then the type
+specifier that is a subtype of other specifiers is selected. For example, type
+specifiers fixnum, <literal>(mod 3)</literal>, and <literal>(member 0 1)</literal> are all
+converted to fixnum, though they are also subtypes of <replaceable>T</replaceable>.</para>
+<para>Because of this type specifier conversion, &ECL; may sometimes regard two
+seemingly distinct declarations as the same. For example, the following
+<literal>type</literal> declarations are completely equivalent, internally in &ECL;.</para>
+<programlisting>
+(declare (type fixnum x)))
+
+(declare (type (mod 3) x))
+
+(declare (type (member 0 1) x))
+</programlisting>
+<para>Type specifiers in declaration specifications passed to the &ECL; specific
+function <literal>proclamation</literal> are also converted to significant type specifiers.
+Thus, for example,</para>
+<para><screen>
+>(proclaim '(function foo (fixnum) fixnum))
+nil
+>(proclamation '(function foo ((mod 3)) (member 0 1)))
+t
+>(proclamation '(function foo (number) character))
+nil
+</screen></para>
+<para>The first call to <literal>proclamation</literal> returns <replaceable>T</replaceable> because both <literal>(mod
+3)</literal> and <literal>(member 0 1)</literal> are converted to fixnum before the
+function type of <literal>foo</literal> is checked.</para>
+</section>
+
+<section xml:id="Type-declarations">
+<title>Treatment of Type Declarations</title>
+<para>&ECL; uses several runtime stacks.</para>
+<para>Arguments to functions, lexical and temporary variables are allocated on the C
+stack. Temporary values saved on the C stack may sometimes be represented as
+<replaceable>raw data</replaceable> instead of pointers to heap-allocated cells. Accessing such raw
+data on the C stack results in faster compiled code, partly because no pointer
+dereferencing operation is necessary, and partly because no cell is newly
+allocated on the heap when a new object is created. This is particularly
+helpful for numeric code which computes with floating point numbers.</para>
+<para>&ECL; uses a conservative garbage collector to scan the C stack and find
+references to live object.</para>
+</section>
+
+<section xml:id="Variable-allocations">
+<title>Variable Allocations</title>
+<para>If a lexical variable is declared to be of fixnum, <literal>character</literal>,
+<literal>short-float</literal>, <literal>long-float</literal>, or their subtypes, then it is allocated
+on the C stack rather than on the value stack. In addition, the variable
+always has a raw datum as its value: 32 bit signed integer for fixnums, 8 bit
+character code with 24 bit padding for characters (remember that the font and
+bit fields of &ECL; characters are always 0), 32 bit floating point
+representation for short-floats, and 64 bit floating point representation for
+long-floats. Similarly, if a lexical variable is named in an <literal>object</literal>
+declaration (see Section 7.1), then it is allocated on the C stack but, in this
+case, the variable always has a cell pointer as its value. The user is
+strongly recommended to make sure that objects stored in such an <literal>object</literal>
+variable may never be garbage collected unexpectedly. For example,</para>
+<programlisting>
+(do ((x (foo) (cdr x)))
+((endp x))
+(let ((y (car x)))
+(declare (object y))
+(bar y)))
+</programlisting>
+<para role="continues">this <literal>object</literal> declaration is completely safe because the value of the
+variable <replaceable>y</replaceable> is always a substructure of the value of <replaceable>x</replaceable>, which in
+turn is protected against garbage collection. Incidentally, loop variables of
+<literal>dolist</literal> may always be declared as object variables, since the
+<literal>dolist</literal> form has essentially the same control structure as the <literal>do</literal>
+form above. On the other hand, the result of evaluation of the following form
+is unpredictable, because the cons cell pointed to from the <literal>object</literal>
+variable <replaceable>z</replaceable> may be garbage collected before <literal>bar</literal> is called.</para>
+<programlisting>
+(let ((z (cons x y)))
+(declare (object z))
+(foo (cons x y))
+(bar z))
+</programlisting>
+<para>Lexical variables that are not declared to be of fixnum,
+character, short-float, long-float, or their
+subtypes, and that are not named in <literal>object</literal> declarations are usually
+allocated on the value stack, but may possibly be allocated on the C stack
+automatically by the compiler.</para>
+</section>
+
+<section xml:id="Raw-data-functions">
+<title>Built-in Functions that Operate on Raw Data Directly</title>
+<para>Some built-in Common-Lisp functions can directly operate on raw data, if
+appropriate declarations are supplied. The addition function <literal>+</literal> is among
+such functions.</para>
+<programlisting>
+(let ((x 1))
+(declare (fixnum x))
+...
+(setq x (+ x 2))
+...
+)
+</programlisting>
+<para>In the compiled code for this <literal>let</literal> form, the raw fixnum datum (i.e., the
+32 bit signed integer) stored in <replaceable>x</replaceable> is simply incremented by 2 and the
+resulting 32 bit signed integer is stored back into <replaceable>x</replaceable>. The compiler is
+sure that the addition for 32 bit signed integers will be performed on the call
+to <literal>+</literal>, because the arguments are both fixnums and the return value must
+be also a fixnum since the value is to be assigned to the fixnum
+variable. The knowledge of both the argument types and the return type is
+necessary for this decision: Addition of two fixnums may possibly produce a
+bignum and addition of two bignums may happen to produce a fixnum value. If
+either the argument type or the return type were not known to the compiler, the
+general addition function would be called to handle the general case. In the
+following form, for example, the compiler cannot be sure that the return value
+of the multiplication is a fixnum or that the arguments of the addition are
+fixnums.</para>
+<programlisting>
+(setq x (+ (* x 3) 2))
+</programlisting>
+<para>In order to obtain the optimal code, a <literal>the</literal> special form should
+surround the multiplication.</para>
+<programlisting>
+(setq x (+ (the fixnum (* x 3)) 2))
+</programlisting>
+<para>Built-in Common-Lisp functions that can directly operate on raw data are:</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>arithmetic functions such as <literal>+</literal>, <literal>-</literal>,
+<literal>1+</literal>, <literal>1-</literal>, <literal>*</literal>, <literal>floor</literal>, <literal>mod</literal>, <literal>/</literal>, and
+<literal>expt</literal>.</para>
+</listitem>
+<listitem>
+<para>predicates such as <literal>eq</literal>, <literal>eql</literal>, <literal>equal</literal>,
+<literal>zerop</literal>, <literal>plusp</literal>, <literal>minusp</literal>, <literal>=</literal>, <literal>/=</literal>, <literal><</literal>,
+<literal><=</literal>, <literal>></literal>, <literal>>=</literal>, <literal>char=</literal>, <literal>char/=</literal>, <literal>char<</literal>,
+<literal>char<=</literal>, <literal>char></literal>, and <literal>char>=</literal>.</para>
+</listitem>
+<listitem>
+<para>sequence processing functions that receive or return one or more
+fixnum values, such as <literal>nth</literal>, <literal>nthcdr</literal>, <literal>length</literal>, and
+<literal>elt</literal>.</para>
+</listitem>
+<listitem>
+<para>array access functions such as <literal>svref</literal>, <literal>char</literal>, <literal>schar</literal>,
+and <literal>aref</literal> (see below).</para>
+</listitem>
+<listitem>
+<para>system-internal functions for array update (see below).</para>
+</listitem>
+<listitem>
+<para>type-specific functions such as <literal>char-code</literal>, <literal>code-char</literal>,
+and <literal>float</literal>.</para>
+</listitem>
+</orderedlist>
+<para>As mentioned in Section 2.5.1, array elements are represented in one of six
+ways depending on the type of the array. By supplying appropriate array type
+declarations, array access and update operations can handle raw data stored in
+arrays. For example,</para>
+<programlisting>
+(let ((a (make-array n :element-type 'fixnum))
+(sum 0))
+(declare (type (array fixnum) a)
+(fixnum sum))
+(dotimes (i n) ;;; Array initialization.
+(declare (fixnum i))
+(setf (aref a i) i))
+....
+(dotimes (i n) ;;; Summing up the elements.
+(declare (fixnum i))
+(setq sum (+ (aref a i) sum)))
+....
+)
+</programlisting>
+<para>The <literal>setf</literal> form replaces the <literal>i-th</literal> element of the array a by the raw
+fixnum value of <literal>i</literal>. The <literal>aref</literal> form retrieves the raw fixnum datum
+stored in <literal>a</literal>. This raw datum is then added to the raw fixnum value of
+the fixnum variable <literal>sum</literal>, producing the raw fixnum datum to be stored in
+<literal>sum</literal>. Similar raw data handling is possible for arrays of types
+<literal>(array fixnum), (vector fixnum),
+(array string-char), string,
+(array short-float), (vector short-float),
+(array long-float)</literal>, and <literal>(vector long-float)</literal>.</para>
+</section>
+
+<section xml:id="Arguments-Values-passing">
+<title>Arguments/Values Passing</title>
+<para>Function proclamations <literal>(function <replaceable>function-name</replaceable> (<replaceable>arg-type1</replaceable>
+<replaceable>arg-type2</replaceable> ...) <replaceable>return-type</replaceable>)</literal> or its equivalents give the compiler
+the chance to generate compiled code so that arguments to the named functions
+and resulting values of the named functions will be passed via the C stack,
+thus increasing the efficiency of calls to these functions. Such
+arguments/values passing via the C stack is possible only if the called
+function is also defined in the same source file. This is because the code for
+the called function must have two entries: One entry for C arguments/values
+passing and another for ordinary Lisp arguments/values passing. (An ordinary
+function has only the latter entry.) When the latter entry is used, the
+arguments are <emphasis>unboxed</emphasis> and passed to the former entry. On return from
+the function, the resulting value is cast into a Lisp data type.</para>
+<para>A good example of this follows.</para>
+<programlisting>
+(eval-when (compile)
+(proclaim '(function tak (fixnum fixnum fixnum) fixnum)))
+
+(defun tak (x y z)
+(declare (fixnum x y z))
+(if (not (< y x))
+z
+(tak (tak (1- x) y z)
+(tak (1- y) z x)
+(tak (1- z) x y))))
+
+;;; Call (tak 18 12 6).
+</programlisting>
+<para>When <literal>tak</literal> is called with the arguments <literal>18, 12</literal>, and <literal>6</literal>, the
+raw fixnum data of the arguments are set to the parameters <literal>x</literal>, <literal>y</literal>,
+<literal>z</literal>. After that, only raw C data are used to perform the execution: No
+cell pointers are newly allocated nor even referenced. The built-in functions
+<literal><</literal> and <literal>1-</literal> directly operate on the raw data. Only at the return from
+the top-level call of <literal>tak</literal>, the resulting raw data value (which happens
+to be <literal>7</literal>) is reallocated on the heap. Note that both the <literal>function</literal>
+proclamation and the local fixnum declaration are necessary to
+obtain the optimal code. The <literal>function</literal> proclamation is necessary for
+arguments/values passing via the C stack and the fixnum declaration
+is necessary to unbox the parameters into C variables.</para>
+</section>
+</chapter>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+--></book>
--- /dev/null
+ <bibliomixed>
+ <bibliomset xreflabel="ANSI" xml:id="bib.ANSI" relation="book">
+ <title>ANSI Common Lisp Specification, ANSI/X3.226-1994</title>.
+ <corpname>ANSI</corpname>, <pubdate>1994</pubdate>.
+ </bibliomset>
+
+ <bibliomset xreflabel="Hyperspec" xml:id="bib.Hyperspec" relation="webdoc">
+ <firstname>Kent M.</firstname> <surname>Pitman</surname>.
+ <title>Common Lisp HypersSpec</title>,
+ <bibliomisc><ulink url="http://www.lisp.org/HyperSpec/FrontMatter/index.html">
+ <uri>http://www.lisp.org/HyperSpec/FrontMatter/index.html</uri></ulink></bibliomisc>
+ </bibliomset>
+
+ <bibliomset xreflabel="CLTL" xml:id="bib.CLTL" relation="book">
+ <firstname>Guy L.</firstname> <surname>Steel Jr.</surname>.
+ <title>Common Lisp: the Language</title>.
+ <publishername>Digital Press</publishername>, <pubdate>1984</pubdate>.
+ </bibliomset>
+
+ <bibliomset xreflabel="CLTL2" xml:id="bib.CLTL2" relation="book">
+ <firstname>Guy L.</firstname> <surname>Steel Jr.</surname>.
+ <title>Common Lisp: the Language II</title>.
+ <publishername>Digital Press</publishername>, <pubdate>1990</pubdate>.
+ </bibliomset>
+
+ <bibliomset xreflabel="KCL" xml:id="bib.KCL" relation="book">
+ <surname>Taiichi</surname> <firstname>Yuasa</firstname> and
+ <surname>Masami</surname> <firstname>Hagiya</firstname>.
+ <title>Kyoto Common-Lisp Report</title>,
+ <publishername>Research Institute for Mathematical Sciences, Kyoto University</publishername>,
+ <pubdate>1988</pubdate>.
+ </bibliomset>
+ </bibliomixed>
--- /dev/null
+html { background: #FFF; }
+body {
+ margin: 1em 125px 0 10%;
+ line-height: 1.5em;
+ padding: 0 2em 1em 2em;
+ background: #FFF;
+ font: 12px Verdana,Arial, sans-serif
+}
+ul, dd, dl, dt { margin-top: 0; margin-bottom: 0; }
+p, code, td, dl, dt {
+ line-height: 1.5em;
+}
+table {
+ font: inherit;
+}
+th, td {
+ vertical-align: top;
+}
+h1, h2, h3, h4, h5 { background: #EEE; }
+code, pre {
+ font-size: 1em;
+ font-family: fixed;
+}
+pre {
+ line-height: 1em;
+ overflow: auto;
+}
+pre.screen {
+ font-weight: bold;
+ background: #EEE;
+ border: 1px solid black;
+ padding: 0.5em;
+}
+pre.programlisting {
+ background: #EEEEEE;
+ border-left: 1px solid black;
+ border-top: 1px solid black;
+ padding: 0.5em;
+}
+a { color: #000; font-weight: bold; }
+div p { padding: 0 2em }
+li p { padding: 0; margin: 0 }
+hr { display: none; }
+div.funcsynopsis p {
+ text-indent: -2em;
+}
+div.variablelist {
+ padding: 0 2em;
+}
+.type, .funcsynopsis, .symbol {
+ font-family: fixed;
+}
+.type, .symbol, .replaceable {
+ white-space: nowrap;
+}
--- /dev/null
+<!ENTITY html.stylesheet "base.css">
+<!ENTITY tex "TeX">
+<!ENTITY latex "LaTeX">
+<!ENTITY CommonLisp "Common Lisp">
+<!ENTITY ECL "<application xmlns='http://docbook.org/ns/docbook'>ECL</application>">
+<!ENTITY CMUCL "<application xmlns='http://docbook.org/ns/docbook'>CMUCL</application>">
+<!ENTITY SBCL "<application xmlns='http://docbook.org/ns/docbook'>SBCL</application>">
+<!ENTITY FFI "<application xmlns='http://docbook.org/ns/docbook'>FFI</application>">
+<!ENTITY UFFI "<link xmlns='http://docbook.org/ns/docbook' linkend='part.uffi'><application xmlns='http://docbook.org/ns/docbook'>UFFI</application></link>">
+<!ENTITY CFFI "<application xmlns='http://docbook.org/ns/docbook'>CFFI</application>">
+<!ENTITY ASDF "<application xmlns='http://docbook.org/ns/docbook'>ASDF</application>">
+<!ENTITY FASL "<acronym xmlns='http://docbook.org/ns/docbook'>FASL</acronym>">
+<!ENTITY ANSI "<xref xmlns='http://docbook.org/ns/docbook' linkend='bib.ANSI'/>">
+<!ENTITY AMOP "<xref xmlns='http://docbook.org/ns/docbook' linkend='bib.AMOP'/>">
+<!ENTITY CLOS "<acronym xmlns='http://docbook.org/ns/docbook'>CLOS</acronym>">
+<!ENTITY PCL "<acronym xmlns='http://docbook.org/ns/docbook'>PCL</acronym>">
+<!ENTITY Steele84 "<xref xmlns='http://docbook.org/ns/docbook' linkend='bib.CLTL2'/>">
+<!ENTITY HyperSpec "<xref xmlns='http://docbook.org/ns/docbook' linkend='bib.HyperSpec'/>">
+<!ENTITY GFDL SYSTEM "tmp/COPYING.GFDL.xml">
+<!ENTITY optional "&optional">
+<!ENTITY rest "&rest">
+<!ENTITY key "&key">
+<!ENTITY allow-other-keys "&allow-other-keys">
+<!ENTITY aux "&aux">
+<!ENTITY body "&body">
+<!ENTITY whole "&whole">
+<!ENTITY environment "&environment">
+<!ENTITY uffi "<application xmlns='http://docbook.org/ns/docbook'><emphasis>UFFI</emphasis></application>">
+<!ENTITY ffi "<acronym xmlns='http://docbook.org/ns/docbook'>FFI</acronym>">
+<!ENTITY LW "<application xmlns='http://docbook.org/ns/docbook'>Lispworks</application>">
+<!ENTITY OpenMCL "<application xmlns='http://docbook.org/ns/docbook'>OpenMCL</application>">
+<!ENTITY MCL "<application xmlns='http://docbook.org/ns/docbook'>MCL</application>">
+<!ENTITY ACL "<application xmlns='http://docbook.org/ns/docbook'>AllegroCL</application>">
+<!ENTITY t "<constant xmlns='http://docbook.org/ns/docbook'>T</constant>">
+<!ENTITY nil "<constant xmlns='http://docbook.org/ns/docbook'>NIL</constant>">
+<!ENTITY NULL "<constant xmlns='http://docbook.org/ns/docbook'>NULL</constant>">
+<!ENTITY C "<acronym xmlns='http://docbook.org/ns/docbook'>C</acronym>">
+<!ENTITY defsystem "<application xmlns='http://docbook.org/ns/docbook'>defsystem</application>">
+<!ENTITY clhs "http://www.lispworks.com/documentation/HyperSpec/Body/">
+<!ENTITY cygwin "<ulink xmlns='http://docbook.org/ns/docbook' url='http://www.cygwin.com/'><application xmlns='http://docbook.org/ns/docbook'>Cygwin</application></ulink>">
+<!ENTITY mingw "<ulink xmlns='http://docbook.org/ns/docbook' url='http://mingw.sourceforge.net/'><application xmlns='http://docbook.org/ns/docbook'>Mingw</application></ulink>">
+<!ENTITY OCL "<link xmlns='http://docbook.org/ns/docbook' linkend='ansi.OCL'>[Only in Common Lisp]</link>">
+<!ENTITY ANSI-C-Dict "Common Lisp and C equivalence">
+<!ENTITY nil "<symbol xmlns='http://docbook.org/ns/docbook'>nil</symbol>">
+<!ENTITY t "<symbol xmlns='http://docbook.org/ns/docbook'>t</symbol>">
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+
+<title>The &ECL; manual</title>
+
+<info>
+<author><personname><firstname>Juan Jose</firstname><surname>Garcia-Ripoll</surname></personname></author>
+<date>$date$</date>
+</info>
+
+ <xi:include href="preface.xmlf" xpointer="preface" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+ <part xml:id="part.standards"><title>Standards</title>
+ <xi:include href="ansi_overview.xml" xpointer="ansi.overview" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_evaluation.xml" xpointer="ansi.evaluation-and-compilation" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_types.xml" xpointer="ansi.types-and-classes" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_data_flow.xml" xpointer="ansi.data-and-control" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_structures.xml" xpointer="ansi.structures" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_conditions.xml" xpointer="ansi.conditions" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_objects.xml" xpointer="ansi.objects" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_symbols.xml" xpointer="ansi.symbols" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_packages.xml" xpointer="ansi.packages" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_numbers.xml" xpointer="ansi.numbers" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_characters.xml" xpointer="ansi.characters" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_conses.xml" xpointer="ansi.conses" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_arrays.xml" xpointer="ansi.arrays" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_strings.xml" xpointer="ansi.strings" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_sequences.xml" xpointer="ansi.sequences" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_hash_tables.xml" xpointer="ansi.hash-tables" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_filenames.xml" xpointer="ansi.filenames" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_files.xml" xpointer="ansi.files" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_streams.xml" xpointer="ansi.streams" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_printer.xml" xpointer="ansi.printer" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_reader.xml" xpointer="ansi.reader" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_system_construction.xml" xpointer="ansi.system-construction" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ansi_environment.xml" xpointer="ansi.environment" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ </part>
+
+ <part xml:id="part.extensions">
+ <title>Extensions and Libraries</title>
+ <xi:include href="asdf.xmlf" xpointer="element(ext.asdf)" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="os.xmlf" xpointer="ext.os" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="ffi.xmlf" xpointer="ext.ffi" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="mp.xmlf" xpointer="ext.mp" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="memory.xmlf" xpointer="ext.memory" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="mop.xmlf" xpointer="ext.mop" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="signals.xmlf" xpointer="ext.signals" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="embed.xmlf" xpointer="ext.embed" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ </part>
+
+ <xi:include href="internals.xmlf" xpointer="part.internals" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+ <part xml:id="part.uffi">
+ <title>UFFI Reference</title>
+ <xi:include href="uffi/ref_primitive.xml" xpointer="uffi.primitives" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="uffi/ref_aggregate.xml" xpointer="uffi.aggregates" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="uffi/ref_object.xml" xpointer="uffi.objects" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="uffi/ref_string.xml" xpointer="uffi.strings" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="uffi/ref_func_libr.xml" xpointer="uffi.func_libr" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ </part>
+
+ <index type="cl">
+ <title>Common Lisp symbols</title>
+ </index>
+
+ <index type="c">
+ <title>C/C++ index</title>
+ </index>
+
+ <xi:include href="bibliography.xmlf" xpointer="Bibliography" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-indent-step: 1
+ nxml-child-indent: 0
+ nxml-outline-child-indent: 0
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="Internals">
+ <title>Internals</title>
+ <para>&ECL; is an implementation of the Common-Lisp language that is based on a kernel
+ written in C plus a set of libraries written in Common-Lisp. The kernel includes a
+ bytecodes compiler, an interpreter, and enough functions to create and
+ manipulate all lisp objects. The lisp libraries provide higher level constructs
+ such as macro definitions, LOOPs, an implementation of CLOS, and a translator
+ from Lisp to C.</para>
+ <para>As a result of this design, which dates back to the Kyoto CL and was later
+ improved in Giuseppe Attardi's ECoLisp, &ECL; can be used as</para>
+ <itemizedlist mark="bullet">
+ <listitem>
+ <para>As a standalone implementation of the Common-Lisp language</para>
+ </listitem>
+ <listitem>
+ <para>As an embedded interpreter subject to the control of a larger C program.</para>
+ </listitem>
+ <listitem>
+ <para>As a Common-Lisp environment with C/C++ extensions.</para>
+ </listitem>
+ </itemizedlist>
+ <para role="continues">This manual describes the facility of &ECL; to interface the C language and
+ &ECL;. With this facility, the user can arrange his or her C-language
+ programs so that they can be invoked from &ECL;. In addition, the user can
+ write Lisp function definitions in the C language to increase runtime
+ efficiency.</para>
+
+ <section xml:id="Building-programs">
+ <title>Building programs</title>
+ <para>In this section we describe how you can use &ECL; to build programs and
+ loadable extensions that you can later on distribute to other people.</para>
+
+ <sect1 label="2.1" xml:id="What-can-ECL-do-">
+ <title>What can &ECL; do?</title>
+ <para>Some day for some reasons you will be in the need to distribute code that
+ has been developed using &ECL;. In the following sections we will describe
+ the means that &ECL; offers you to do so. Basically, these are the
+ alternatives</para>
+ <variablelist>
+ <varlistentry>
+ <term>Source code</term>
+ <listitem>
+ <para>You distribute your programs in source code form. This is the easiest and most
+ portable way, but not the fastest one.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Standalone programs</term>
+ <listitem>
+ <para>You translate all your lisp code to C using the &ECL; compiler. The final
+ object files can be linked against other C/C++ libraries to obtain a standalone
+ executable.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>You can build statically and dynamically linked libraries.</term>
+ <listitem>
+ <para>You translate all your lisp code to C and combine the resulting object files
+ into a single library with <filename>.a</filename> extension. You can distribute this library
+ to other people and the final users can utilize these libraries to build
+ standalone programs.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>You can build dynamically loadable files.</term>
+ <listitem>
+ <para>This is the most flexible way. You translate all lisp code to C and link it
+ against possibly other C/C++ libraries to obtain a dynamically loadable library
+ (file type <filename>.so</filename> under unix). This library can be loaded a startup time to
+ add new functionality to the &ECL; environment.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>In several of these options, we have mentioned the possibility to include C/C++
+ code. Even if this is possible, you cannot use ordinary C/C++ compilers and
+ makefiles to build &ECL; extensions, let it be programs or
+ libraries. Briefly, you have to organize your code as follows</para>
+ <orderedlist numeration="arabic">
+ <listitem>
+ <para>Organize the C code as a library, let it be static or dynamic.</para>
+ </listitem>
+ <listitem>
+ <para>Build a function, say <literal>mymain()</literal>, in which the initialization phase
+ for your library is performed.</para>
+ </listitem>
+ <listitem>
+ <para>Group the code that interfaces to Lisp in separate C files, all of which
+ should include <literal>#include <ecl/ecl.h></literal> at the beginning.</para>
+ </listitem>
+ <listitem>
+ <para>Compile your lisp source files.</para>
+ </listitem>
+ <listitem>
+ <para>Let &ECL; build the final executable or library.</para>
+ </listitem>
+ </orderedlist>
+ <para role="continues">In the final step there are ways to instruct &ECL; to call your
+ initialization function (<literal>mymain()</literal> in the example above). These means
+ are explained in the following sections.</para>
+ <!-- -->
+ </sect1>
+
+ <sect1 label="2.2" xml:id="Compiling-files">
+ <title>Compiling files</title>
+ <para>&ECL; supports two types of compilation. One is bytecodes compilation. This
+ process is performed on-the-fly, as you load source files with lisp code. This
+ leads to a series of bytes for each instruction, the so called
+ "bytecodes". These bytecodes are interpreted in a virtual machine, which is
+ written in C and which is reasonably fast.</para>
+ <para>The other type of compilation is the so-called "native" compilation. This
+ process consists on translating the lisp source file to C language. The
+ intermediate file is later compiled using a C compiler. The result is an object
+ file which may have different purposes.</para>
+ <variablelist>
+ <varlistentry>
+ <term>Dynamically loadable files or FASL (FASt Loadable) files</term>
+ <listitem>
+ <para>These are produced in a &ECL; built with support for dynamically loadable
+ libraries (Feature <replaceable>:DLOPEN</replaceable> is in <replaceable>*features*</replaceable>), when no extra
+ arguments are passed to <literal>compile-file</literal>. These object files typically have
+ the <filename>.fas</filename> extension, and can be loaded with <literal>load</literal>. They cannot be used
+ to build libraries nor standalone executable programs.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>linkable object files</term>
+ <listitem>
+ <para>These are produced when invoking <literal>compile-file</literal> with the keyword argument
+ <replaceable>:system-p</replaceable> set to true. The object file typically has the <filename>.o</filename>
+ extension. It cannot be loaded with <literal>load</literal>, but it can be used to build
+ libraries, standalone executable programs, or larger FASL files.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <!-- -->
+ </sect1>
+
+ <sect1 label="2.3" xml:id="Building-standalone-executables">
+ <title>Building standalone executables</title>
+ <para>To build an executable you need a working &ECL; image with the
+ compiler. The function to build customized images is
+ <replaceable>c::build-program</replaceable>. The description of this function is as
+ follows. Care should be taken that <replaceable>image-name</replaceable> differs from any
+ filename in <replaceable>lisp-files</replaceable>.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>c:build-program</primary></indexterm>— Function: <function>c:build-program</function> <varname>{</varname><varname>image-name</varname> <varname>&key</varname> <varname>lisp-files</varname> <varname>ld-flags</varname> <varname>prologue-code</varname> <varname>epilogue-code</varname><varname>}</varname></screen>
+ <para>This function builds a lisp image up from the core lisp library, plus all
+ components listed in <replaceable>lisp-files</replaceable>. Each component is either:</para>
+ <itemizedlist mark="bullet">
+ <listitem>
+ <para>A symbol: Names a statically linked library built from lisp code.</para>
+ </listitem>
+ <listitem>
+ <para>A string: Denotes an object file built from lisp code.</para>
+ </listitem>
+ </itemizedlist>
+ <para role="continues"><replaceable>ld-flags</replaceable> is a list of strings with additional parameters to be passed
+ to the linker. You can include here your favorite C/C++ libraries.</para>
+ <para><replaceable>prologue-code</replaceable> and <replaceable>epilogue-code</replaceable> are used to customize the
+ initialization process of the lisp image. In order to build the executable,
+ <replaceable>c:build-program</replaceable> first writes down a piece of C code which initializes the
+ lisp environment. You can customize the initialization process by suppling code
+ to be executed before (<replaceable>prologue-code</replaceable>) or after (<replaceable>epilogue-code</replaceable>)
+ setting up the lisp environment. Typically <replaceable>prologue-code</replaceable> defaults to an
+ empty string, while <replaceable>epilogue-code</replaceable> invokes the classical lisp
+ <replaceable>top-level</replaceable>. Additionally, as a convenience, <replaceable>epilogue-code</replaceable> can
+ be either a string with C code or also a list with a lisp form, which
+ will be interpreted at run time.</para>
+ </blockquote>
+ <!-- -->
+ </sect1>
+
+ <sect1 label="2.4" xml:id="Building-libraries">
+ <title>Building libraries</title>
+ <para>To build a library you proceed more or less the same way as with standalone
+ executables. There are two different functions depending on whether you need
+ to build static or shared libraries.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>c:build-static-library</primary></indexterm>— Function: <function>c:build-static-library</function> <varname>{</varname><varname>library-name</varname> <varname>&key</varname> <varname>lisp-files</varname> <varname>prologue-code</varname> <varname>epilogue-code</varname> <varname>init-name</varname><varname>}</varname></screen>
+ <screen><indexterm role="fn"><primary>c:build-shared-library</primary></indexterm>— Function: <function>c:build-shared-library</function> <varname>{</varname><varname>library-name</varname> <varname>&key</varname> <varname>lisp-files</varname> <varname>prologue-code</varname> <varname>epilogue-code</varname> <varname>ld-flags</varname> <varname>init-name</varname><varname>}</varname></screen>
+ <para>This function builds a library file up from the object files listed in
+ <replaceable>lisp-files</replaceable>. Each of the arguments to <replaceable>lisp-file</replaceable> must name a single
+ object file produced with <literal>compile-file</literal>.</para>
+ <para><replaceable>library-name</replaceable> is the physical pathname corresponding to the library. The
+ value of <replaceable>library-name</replaceable> must follow some system-specific conventions. To
+ make your program portable, <replaceable>library-name</replaceable> should be built using the
+ output of <literal>compile-file-pathname</literal>.</para>
+ <para><replaceable>prologue-code</replaceable> and <replaceable>epilogue-code</replaceable> are strings with C code to be
+ executed before and after initializing the library, respectively. For
+ dynamically linked libraries you can also provide a list of strings in
+ <replaceable>ld-flags</replaceable>. These strings are additional parameters for the linker and
+ their purpose is to link C/C++ extensions into the library.</para>
+ <para><replaceable>init-name</replaceable> gives the initialization function of the library a
+ user-specified name. Thus a the generated library may be used and/or
+ linked to a C application.</para>
+ </blockquote>
+ <!-- -->
+ </sect1>
+
+ <sect1 label="2.5" xml:id="File-names">
+ <title>File names</title>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>compile-file-pathname</primary></indexterm>— Function: <function>compile-file-pathname</function> <varname>{</varname><varname>filename-base</varname> <varname>&key</varname> <varname>output-file</varname> <varname>type</varname><varname>}</varname></screen>
+ <para>When compiling lisp files, creating libraries, etc, a number of files are
+ produced which are of interest for the user or programmer. However, the name
+ of these files will change from system to system. The purpose of the function
+ <literal>compile-file-pathname</literal> is to query the compiler about the name of the
+ different files that it can produce. Possible values of the <replaceable>type</replaceable>
+ argument include:</para>
+ <variablelist>
+ <varlistentry>
+ <term>:fas (default)</term>
+ <listitem>
+ <para>Standard compiled files that can be loaded with <literal>load</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>:c, :data, :h</term>
+ <listitem>
+ <para>Intermediate files produced by the Lisp-to-C translator.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>:o</term>
+ <listitem>
+ <para>Linkable object files.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>:lib, :static-library</term>
+ <listitem>
+ <para>A normal library produced with <literal>c:build-static-library</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>:dll, :shared-library</term>
+ <listitem>
+ <para>A dynamically linked library produced with <literal>c:build-shared-library</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>:program</term>
+ <listitem>
+ <para>An executable produced with <literal>c:build-program</literal>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>The output of this function is system specific. For example, under FreeBSD<screen>
+ > (compile-file-pathname "/this/path/mylib" :type :lib)
+ #P"/this/path/libmylib.a"
+ > (compile-file-pathname "/this/path/mylib" :type :dll)
+ #P"/this/path/libmylib.so"
+ > (compile-file-pathname "/this/path/mycode")
+ #P"/this/path/mycode.fas"
+ </screen></para>
+ </blockquote>
+ <!-- -->
+ </sect1>
+
+ <sect1 label="2.6" xml:id="Compiler-examples">
+ <title>Compiler examples</title>
+ <sect2 label="2.6.1">
+ <title>The <filename>hello.lisp</filename> file</title>
+ <para>In the following examples we will use the same lisp program. You have to
+ create a file called <filename>hello.lisp</filename> which contains the following lines</para>
+ <programlisting>
+ (princ "Hello world!")
+ (terpri)
+ (quit)
+ </programlisting>
+ <para role="continues">If you start &ECL; and load this file in the Common-Lisp environment you
+ will see the <literal>"Hello world!"</literal> message and the interpreter will be closed.<screen>
+ ECL (Embeddable Common-Lisp) 0.9d
+ Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
+ Copyright (C) 1993 Giuseppe Attardi
+ Copyright (C) 2000 Juan J. Garcia-Ripoll
+ ECL is free software, and you are welcome to redistribute it
+ under certain conditions; see file 'Copyright' for details.
+ Type :h for Help. Top level.
+ > <lineannotation>(load "hello.lisp")</lineannotation>
+ ;;; Loading "hello.lisp"
+ Hello World!
+ </screen></para>
+ </sect2>
+
+ <sect2 label="2.6.2">
+ <title>Example of loadable object file</title>
+ <para>You can only perform the example in this section if your &ECL; image supports
+ dynamically loading of object files. This is true if you find the keyword
+ <replaceable>:dlopen</replaceable> in the <replaceable>*features*</replaceable> variable. This is true, for instance,
+ in a typical FreeBSD or Linux box,<screen>
+ Type :h for Help. Top level.
+ > <lineannotation>*features*</lineannotation>
+ (:IEEE-FLOATING-POINT :IBM-PC :I386 :BSD :UNIX :DLOPEN :ANSI-CL :CLOS
+ :BOEHM-GC :ECL :COMMON)
+ </screen></para>
+ <para>In this example we build a loadable extension which prints the <literal>"Hello
+ world!"</literal> message. First you need to create a the <filename>hello.lisp</filename> file. Next
+ you have to enter the &ECL; environment and type <literal>(compile-file
+ "hello.lisp")</literal>. This produces a loadable object file.</para>
+ <para><screen>
+ Type :h for Help. Top level.
+ > <lineannotation>(compile-file "hello.lisp")</lineannotation>
+ ;;; Loading #P"/usr/lib/ecl/cmp.fas"
+ ;;; Loading #P"/usr/lib/ecl/sysfun.lsp"
+ ;;; Compiling hello.lisp.
+ ;;; End of Pass 1.
+ ;;; Calling the C compiler...
+ ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "hello.c" -o "hello.o"
+ ;;; Invoking external command: gcc -o "hello.fas" -L"/usr/lib/ecl/" "hello.o" -Wl,–rpath,/usr/lib/ecl/ -shared -lecl -lgmp -lgc -ldl -lm
+ ;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3
+ ;;; Finished compiling hello.lisp.
+ #P"hello.fas"
+ Top level.
+ > <lineannotation>(load "hello")</lineannotation>
+ ;;; Loading #P"hello.fas"
+ Hello World!
+ </screen></para>
+ </sect2>
+
+ <sect2 label="2.6.3">
+ <title>Example of standalone program</title>
+ <para>In this example we build a standalone program which prints the <literal>"Hello
+ world!"</literal> message and does nothing else. First you must create the
+ <filename>hello.lisp</filename> file shown above. Next you have to enter the &ECL;
+ environment and type <literal>(compile-file "hello.lisp" :system-p t)</literal>. This
+ produces an object file that can be linked against the &ECL; core image.</para>
+ <para><screen>
+ Type :h for Help. Top level.
+ > <lineannotation>(compile-file "hello.lisp" :system-p t)</lineannotation>
+ ;;; Loading #P"/usr/lib/ecl/cmp.fas"
+ ;;; Loading #P"/usr/lib/ecl/sysfun.lsp"
+ ;;; Compiling hello.lisp.
+ ;;; End of Pass 1.
+ ;;; Calling the C compiler...
+ ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "hello.c" -o "hello.o"
+ ;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3
+ ;;; Finished compiling hello.lisp.
+ #P"hello.o"
+ </screen></para>
+ <para role="continues">The final step is to build the executable using the <literal>c:build-program</literal>
+ instruction.<screen>
+ > <lineannotation>(c:build-program "myecl" :lisp-files '("hello.o"))</lineannotation>
+ ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "myecl.c" -o "myecl.o"
+ ;;; Invoking external command: gcc -o "myecl" -L"/usr/lib/ecl/" "myecl.o" "hello.o" -Wl,–rpath,/usr/lib/ecl/ -lecl -lgmp -lgc -ldl -lm
+ #P"myecl"
+ Top level.
+ </screen>Now you can execute this program from your favorite shell.</para>
+ <para role="continues"><screen>
+ % <lineannotation>./myecl</lineannotation>
+ Hello world!
+ </screen></para>
+ </sect2>
+
+ <sect2 label="2.6.4">
+ <title>Combining files into a larger FASL</title>
+ <para>You can only perform the example in this section if your &ECL; image supports
+ dynamically loading of object files. In this example we build a loadable
+ library which prints the <literal>"Hello world!"</literal> message and does nothing
+ else. First you must create the <filename>hello.lisp</filename> file shown above. Next you
+ have to enter the &ECL; environment and type <literal>(compile-file "hello.lisp"
+ :system-p t)</literal>. This produces an object file that can be linked to form a loadable
+ library.</para>
+ <para><screen>
+ Type :h for Help. Top level.
+ > (compile-file "hello.lisp" :system-p t)
+ ;;; Loading #P"/usr/lib/ecl/cmp.fas"
+ ;;; Loading #P"/usr/lib/ecl/sysfun.lsp"
+ ;;; Compiling hello.lisp.
+ ;;; End of Pass 1.
+ ;;; Calling the C compiler...
+ ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "hello.c" -o "hello.o"
+ ;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3
+ ;;; Finished compiling hello.lisp.
+ #P"hello.o"
+ </screen></para>
+ <para role="continues">The final step is to build the library using the <literal>c:build-fasl</literal>
+ instruction.<screen>
+ > (c:build-fasl "myecl" :lisp-files '("hello.o"))
+ ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "myecl.c" -o "myecl.o"
+ ;;; Invoking external command: gcc -o "libmyecl.so" -L"/usr/lib/ecl/" "myecl.o" "hello.o" -Wl,–rpath,/usr/lib/ecl/ -shared -lecl -lgmp -lgc -ldl -lm
+ #P"libmyecl.so"
+ </screen>Now you can load this extension from any &ECL; image, even those you produce
+ with <literal>c:build-program</literal>.</para>
+ <para role="continues"><screen>
+ <<<<<<<< THIS EXAMPLE IS WRONG?! >>>>>>>>>
+ > (load "myecl")
+ ;;; Loading myecl.fas
+ Hello world!
+ Bye.
+ </screen></para>
+ <!-- -->
+ </sect2>
+ </sect1>
+ </section>
+
+ <section xml:id="Lisp-objects">
+ <title>Manipulating Lisp objects</title>
+ <para>If you want to extend, fix or simply customize &ECL; for your own needs,
+ you should understand how the implementation works.</para>
+
+ <sect1 label="3.1" xml:id="Objects-representation">
+ <title>Objects representation</title>
+ <para>In &ECL; a lisp object is represented by a type called <literal>cl_object</literal>. This
+ type is a word which is long enough to host both an integer and a pointer. The
+ least significant bits of this word, also called the tag bits, determine
+ whether it is a pointer to a C structure representing a complex object, or
+ whether it is an immediate data, such as a fixnum or a character.</para>
+ <screen><![CDATA[
+ |-------------------|--|
+ | Fixnum value |01|
+ |-------------------|--|
+
+ |------------|------|--|
+ | Unused bits| char |10|
+ |------------|------|--|
+
+ |----------------------| |--------|--------|-----|--------|
+ | Pointer to cell |---->| word-1 | word-2 | ... | word-n |
+ |----------------------| |--------|--------|-----|--------|
+ | ...................00| | actual data of the object |
+ |----------------------| |--------------------------------|
+ ]]></screen>
+ <para>The fixnums and characters are called immediate datatypes, because they require
+ no more than the <literal>cl_object</literal> datatype to store all information. All other
+ &ECL; objects are non-immediate and they are represented by a pointer to a
+ cell that is allocated on the heap. Each cell consists of several words of
+ memory and contains all the information related to that object. By storing data
+ in multiples of a word size, we make sure that the least significant bits of a
+ pointer are zero, which distinguishes pointers from immediate data.</para>
+ <para>In an immediate datatype, the tag bits determine the type of the object. In
+ non-immediate datatypes, the first byte in the cell contains the secondary type
+ indicator, and distinguishes between different types of non immediate data. The
+ use of the remaining bytes differs for each type of object. For instance, a
+ cons cell consists of three words:</para>
+ <screen><![CDATA[
+ |---------|----------|
+ |CONS| | |
+ |---------|----------|
+ | car-pointer |
+ |--------------------|
+ | cdr-pointer |
+ |--------------------|
+ ]]></screen>
+ <para>There is one important function which tells the type of an object, plus several
+ macros which group several tests.</para>
+ <blockquote>
+ <screen><indexterm role="tp"><primary>cl_object</primary></indexterm>— C type: <structname>cl_object</structname></screen>
+ <para>This is the type of a lisp object. For your C/C++ program, a <literal>cl_object</literal>
+ can be either a fixnum, a character, or a pointer to a union of structures (See
+ the header <filename>object.h</filename>). The actual interpretation of that object can be
+ guessed with the macro <literal>ecl_t_of</literal>.</para>
+ <para>For example, if <replaceable>x</replaceable> is of type <literal>cl_object</literal>, and it is of type fixnum,
+ we may retrieve its value</para>
+ <screen>
+ if (ecl_t_of(x) == t_fixnum)
+ printf("Integer value: %d\n", fix(x));
+ </screen>
+ <para role="continues">If <replaceable>x</replaceable> is of type <literal>cl_object</literal> and it does not contain an immediate
+ datatype, you may inspect the cell associated to the lisp object using <replaceable>x</replaceable>
+ as a pointer. For example,</para>
+ <screen>
+ if (ecl_t_of(x) == t_cons)
+ printf("CAR = %x, CDR = %x\n", x->cons.car, x->cons.cdr);
+ else if (ecl_t_of(x) == t_string)
+ printf("String: %s\n", x->string.self);
+ </screen>
+ <para role="continues">You should see the following sections and the header <filename>object.h</filename> to learn
+ how to use the different fields of a <literal>cl_object</literal> pointer.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="tp"><primary>cl_type</primary></indexterm>— C type: <structname>cl_type</structname></screen>
+ <para>Enumeration type which distinguishes the different types of lisp objects. The
+ most important values are t_cons, t_fixnum, t_character, t_bignum, t_ratio,
+ t_singlefloat, t_doublefloat, t_complex, t_symbol, t_package, t_hashtable,
+ t_array, t_vector, t_string, t_bitvector, t_stream, t_random, t_readtable,
+ t_pathname, t_bytecodes, t_cfun, t_cclosure, t_gfun, t_instance, t_foreign and
+ t_thread.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>ecl_t_of</primary></indexterm>— Function: <returnvalue>cl_type</returnvalue> <function>ecl_t_of</function> (<type>cl_object</type> <varname>O</varname>)</screen>
+ <para>If <replaceable>O</replaceable> is a valid lisp object, <literal>ecl_t_of(<replaceable>O</replaceable>)</literal> returns an integer
+ denoting the type that lisp object. That integer is one of the values of the
+ enumeration type <literal>cl_type</literal>.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>FIXNUMP</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>FIXNUMP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>CHARACTERP</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>CHARACTERP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>CONSP</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>CONSP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>LISTP</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>LISTP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>ATOM</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>ATOM</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>ARRAYP</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>ARRAYP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>VECTORP</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>VECTORP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>STRINGP</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>STRINGP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Different macros that check whether <replaceable>o</replaceable> belongs to the specified type.
+ These checks have been optimized, and are preferred over several calls to
+ <literal>ecl_t_of</literal>.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>IMMEDIATE</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>IMMEDIATE</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Tells whether <replaceable>o</replaceable> is an immediate datatype.</para>
+ </blockquote>
+ <!-- -->
+ </sect1>
+
+ <sect1 label="3.2" xml:id="Constructing-objects">
+ <title>Constructing objects</title>
+ <para>On each of the following sections we will document the standard interface for
+ building objects of different types. For some objects, though, it is too
+ difficult to make a C interface that resembles all of the functionality in the
+ lisp environment. In those cases you need to</para>
+ <orderedlist numeration="arabic">
+ <listitem>
+ <para>build the objects from their textual representation, or</para>
+ </listitem>
+ <listitem>
+ <para>use the evaluator to build these objects.</para>
+ </listitem>
+ </orderedlist>
+ <para role="continues">The first way makes use of a C or Lisp string to construct an object. The two
+ functions you need to know are the following ones.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>c_string_to_object</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>c_string_to_object</function> (<type>const</type> <varname>char</varname> <type>*</type><varname>s</varname>)</screen>
+ <screen><indexterm role="fn"><primary>string_to_object</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>string_to_object</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para><literal>c_string_to_object</literal> builds a lisp object from a C string which contains a
+ suitable representation of a lisp object. <literal>string_to_object</literal> performs the
+ same task, but uses a lisp string, and therefore it is less useful. Two
+ examples of their use</para>
+ <screen>
+ /* Using a C string */
+ cl_object array1 = c_string_to_object("#(1 2 3 4)");
+
+ /* Using a Lisp string */
+ cl_object string = make_simple_string("#(1 2 3 4)");
+ cl_object array2 = string_to_object(string);
+ </screen>
+ </blockquote>
+ <!-- -->
+ </sect1>
+
+ <sect1 label="3.3" xml:id="Integers">
+ <title>Integers</title>
+ <para>Common-Lisp distinguishes two types of integer types: bignums and fixnums. A
+ fixnum is a small integer, which ideally occupies only a word of memory and
+ which is between the values <replaceable>MOST-NEGATIVE-FIXNUM</replaceable> and
+ <replaceable>MOST-POSITIVE-FIXNUM</replaceable>. A bignum is any integer which is not a fixnum and
+ it is only constrained by the amount of memory available to represent it.</para>
+ <para>In &ECL; a fixnum is an integer that, together with the tag bits, fits in a
+ word of memory. The size of a word, and thus the size of a fixnum, varies from
+ one architecture to another, and you should refer to the types and constants in
+ the <filename>ecl.h</filename> header to make sure that your C extensions are portable.
+ All other integers are stored as bignums, they are not immediate objects, they
+ take up a variable amount of memory and the GNU Multiprecision Library is
+ required to create, manipulate and calculate with them.</para>
+ <blockquote>
+ <screen><indexterm role="tp"><primary>cl_fixnum</primary></indexterm>— C type: <structname>cl_fixnum</structname></screen>
+ <para>This is a C signed integer type capable of holding a whole fixnum without any
+ loss of precision. The opposite is not true, and you may create a
+ <literal>cl_fixnum</literal> which exceeds the limits of a fixnum and should be stored as a
+ bignum.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="tp"><primary>cl_index</primary></indexterm>— C type: <structname>cl_index</structname></screen>
+ <para>This is a C unsigned integer type capable of holding a nonnegative fixnum without
+ loss of precision. Typically, a <literal>cl_index</literal> is used as an index into an array,
+ or into a proper list, etc.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="vr"><primary>MOST_NEGATIVE_FIXNUM</primary></indexterm>— Constant: <varname>MOST_NEGATIVE_FIXNUM</varname></screen>
+ <screen><indexterm role="vr"><primary>MOST_POSITIVE_FIXNUM</primary></indexterm>— Constant: <varname>MOST_POSITIVE_FIXNUM</varname></screen>
+ <para>These constants mark the limits of a fixnum.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>FIXNUM_MINUSP</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>FIXNUM_MINUSP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>FIXNUM_PLUSP</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>FIXNUM_PLUSP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>These functions perform the checks (<replaceable>o</replaceable> < 0) and (0 <= <replaceable>o</replaceable>),
+ respectively.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>MAKE_FIXNUM</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>MAKE_FIXNUM</function> (<type>cl_fixnum</type> <varname>n</varname>)</screen>
+ <screen><indexterm role="fn"><primary>fix</primary></indexterm>— Function: <returnvalue>cl_fixnum</returnvalue> <function>fix</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para><literal>MAKE_FIXNUM</literal> and <literal>fix</literal> convert from an integer to a lisp object
+ of fixnum type and vice versa. These functions no not check their arguments.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>fixint</primary></indexterm>— Function: <returnvalue>cl_fixnum</returnvalue> <function>fixint</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Converts a lisp fixnum to a C integer of the appropriate size. Signals an error
+ if <replaceable>o</replaceable> is not of fixnum type.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>fixnnint</primary></indexterm>— Function: <returnvalue>cl_index</returnvalue> <function>fixnnint</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Similar to <literal>fixint</literal> but also ensures that <replaceable>o</replaceable> is not negative.</para>
+ </blockquote>
+ <!-- -->
+ </sect1>
+
+ <sect1 label="3.4" xml:id="Characters">
+ <title>Characters</title>
+ <para>&ECL; has only one type of characters, which fits in the C type <literal>char</literal>.
+ The following constants and functions operate on characters.</para>
+ <blockquote>
+ <screen><indexterm role="vr"><primary>CHAR_CODE_LIMIT</primary></indexterm>— Constant: <varname>CHAR_CODE_LIMIT</varname></screen>
+ <para>Each character is assigned an integer code which ranges from 0 to
+ (<replaceable>CHAR_CODE_LIMIT</replaceable>-1).</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>CHAR_CODE</primary></indexterm>— Function: <returnvalue>cl_fixnum</returnvalue> <function>CHAR_CODE</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>char_code</primary></indexterm>— Function: <returnvalue>cl_fixnum</returnvalue> <function>char_code</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Returns the integer code associated to a lisp character. Only <literal>char_code</literal>
+ checks its arguments.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>CODE_CHAR</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>CODE_CHAR</function> (<type>cl_fixnum</type> <varname>o</varname>)</screen>
+ <para>Returns the lisp character associated to an integer code. It does not check
+ its arguments.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>coerce_to_character</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>coerce_to_character</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Coerces a lisp object to type character. Valid arguments are a character,
+ or a string designator of length 1. In all other cases an error is signaled.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>char_eq</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>char_eq</function> (<type>cl_object</type> <varname>x</varname>, <type>cl_object</type> <varname>y</varname>)</screen>
+ <screen><indexterm role="fn"><primary>char_equal</primary></indexterm>— Function: <returnvalue>bool</returnvalue> <function>char_equal</function> (<type>cl_object</type> <varname>x</varname>, <type>cl_object</type> <varname>y</varname>)</screen>
+ <para>Compare two characters for equality. <literal>char_eq</literal> take case into account and
+ <literal>char_equal</literal> ignores it.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>char_cmp</primary></indexterm>— Function: <returnvalue>int</returnvalue> <function>char_cmp</function> (<type>cl_object</type> <varname>x</varname>, <type>cl_object</type> <varname>y</varname>)</screen>
+ <screen><indexterm role="fn"><primary>char_compare</primary></indexterm>— Function: <returnvalue>int</returnvalue> <function>char_compare</function> (<type>cl_object</type> <varname>x</varname>, <type>cl_object</type> <varname>y</varname>)</screen>
+ <para>Compare the relative order of two characters. <literal>char_cmp</literal> takes care of
+ case and <literal>char_compare</literal> converts all characters to uppercase before
+ comparing them.</para>
+ </blockquote>
+ <!-- -->
+ </sect1>
+
+ <sect1 label="3.5" xml:id="Arrays">
+ <title>Arrays</title>
+ <para>An array is an aggregate of data of a common type, which can be accessed with
+ one or more nonnegative indices. &ECL; stores arrays as a C structure with a
+ pointer to the region of memory which contains the actual data. The cell
+ of an array datatype varies depending on whether it is a vector, a bytevector,
+ a multidimensional array or a string.</para>
+ <para>If <replaceable>x</replaceable> contains a vector, you can access the following fields:</para>
+ <variablelist>
+ <varlistentry>
+ <term><literal>x->vector.elttype</literal></term>
+ <listitem>
+ <para>The type of the elements of the vector.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->vector.dim</literal></term>
+ <listitem>
+ <para>The maximum number of elements.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->vector.fillp</literal></term>
+ <listitem>
+ <para>Actual number of elements in the vector or "fill pointer".</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->vector.self</literal></term>
+ <listitem>
+ <para>Union of pointers of different types. You should choose the right pointer
+ depending on <literal>x->vector.elltype</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->vector.hasfillp</literal></term>
+ <listitem>
+ <para>Whether <literal>x->vector.fillp</literal> can be smaller than <literal>x->vector.dim</literal>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>If <replaceable>x</replaceable> contains a multidimensional array, the cell elements become</para>
+ <variablelist>
+ <varlistentry>
+ <term><literal>x->array.elttype</literal></term>
+ <listitem>
+ <para>The type of the elements of the array.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->array.dim</literal></term>
+ <listitem>
+ <para>Number of elements in the array.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->array.rank</literal></term>
+ <listitem>
+ <para>Number of dimensions of the array.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->array.dims[]</literal></term>
+ <listitem>
+ <para>Array with the dimensions of the array. The elements range from
+ <literal>x->array.dim[0]</literal> to <literal>x->array.dim[x->array.rank-1]</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->array.self</literal></term>
+ <listitem>
+ <para>Union of pointers to the actual data. You should choose the right pointer
+ depending on <literal>x->array.elltype</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->array.rank</literal></term>
+ <listitem>
+ <para>Whether <literal>x->vector.fillp</literal> can be smaller than <literal>x->vector.dim</literal>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para role="continues">Bitvectors and strings are treated separately.</para>
+ <para>Each array is of an specialized type which is the type of the elements of the
+ array. &ECL; has arrays only a few following specialized types, and for each
+ of these types there is a C integer which is the corresponding value of
+ <literal>x->array.elttype</literal> or <literal>x->vector.elttype</literal>. We list those types
+ together with the C constant that denotes that type:</para>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>T</replaceable></term>
+ <listitem>
+ <para><literal>aet_object</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>CHARACTER</replaceable></term>
+ <listitem>
+ <para><literal>aet_ch</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>FIXNUM</replaceable></term>
+ <listitem>
+ <para><literal>aet_fix</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>BIT</replaceable></term>
+ <listitem>
+ <para><literal>aet_bit</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>SINGLE-FLOAT</replaceable></term>
+ <listitem>
+ <para><literal>aet_sf</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>DOUBLE-FLOAT</replaceable></term>
+ <listitem>
+ <para><literal>aet_df</literal></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>array_elttype</primary></indexterm>— Function: <returnvalue>cl_elttype</returnvalue> <function>array_elttype</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Returns the element type of the array <replaceable>o</replaceable>, which can be a string, a
+ bitvector, vector, or a multidimensional array. For example, the code
+ <literal>array_elttype(c_string_to_object("\"AAA\""))</literal> returns <literal>aet_ch</literal>,
+ while the <literal>array_elttype(c_string_to_object("#(A B C)"))</literal> returns
+ <literal>aet_object</literal>.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>aref</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>aref</function> (<type>cl_object</type> <varname>array</varname>, <type>cl_index</type> <varname>index</varname>)</screen>
+ <screen><indexterm role="fn"><primary>aset</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>aset</function> (<type>cl_object</type> <varname>array</varname>, <type>cl_index</type> <varname>index</varname>, <type>cl_object</type> <varname>value</varname>)</screen>
+ <para>These functions are used to retrieve and set the elements of an array. The
+ elements are accessed with one index, <replaceable>index</replaceable>, as in the lisp function
+ <literal>ROW-MAJOR-AREF</literal>. For example</para>
+ <screen>
+ cl_object array = c_string_to_object("#2A((1 2) (3 4))");
+ cl_object x = aref(array, 3);
+ cl_print(1, x); /* Outputs 4 */
+ aset(array, 3, MAKE_FIXNUM(5));
+ cl_print(1, array); /* Outputs #2A((1 2) (3 5)) */
+ </screen>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>aref1</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>aref1</function> (<type>cl_object</type> <varname>vector</varname>, <type>cl_index</type> <varname>index</varname>)</screen>
+ <screen><indexterm role="fn"><primary>aset1</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>aset1</function> (<type>cl_object</type> <varname>vector</varname>, <type>cl_index</type> <varname>index</varname>, <type>cl_object</type> <varname>value</varname>)</screen>
+ <para>These functions are similar to <literal>aref</literal> and <literal>aset</literal>, but they operate on
+ vectors.</para>
+ <screen>
+ cl_object array = c_string_to_object("#(1 2 3 4)");
+ cl_object x = aref1(array, 3);
+ cl_print(1, x); /* Outputs 4 */
+ aset1(array, 3, MAKE_FIXNUM(5));
+ cl_print(1, array); /* Outputs #(1 2 3 5) */
+ </screen>
+ </blockquote>
+ <!-- -->
+ </sect1>
+
+ <sect1 label="3.6" xml:id="Strings">
+ <title>Strings</title>
+ <para>A string, both in Common-Lisp and in &ECL; is nothing but a vector of
+ characters. Therefore, almost everything mentioned in the section of arrays
+ remains valid here. The only important difference is that &ECL; stores
+ strings as a lisp object with a pointer to a zero terminated C string. Thus, if
+ a string has <replaceable>n</replaceable> characters, &ECL; will reserve <replaceable>n</replaceable>+1 bytes for the
+ string. This allows us to pass the string <literal>self</literal> pointer to any C
+ routine.</para>
+ <para>If <replaceable>x</replaceable> is a lisp object of type string, we can access the following fields:</para>
+ <variablelist>
+ <varlistentry>
+ <term><literal>x->string.dim</literal></term>
+ <listitem>
+ <para>Maximum number of characters that it can contain.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->string.fillp</literal></term>
+ <listitem>
+ <para>Actual number of characters in the string.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->string.self</literal></term>
+ <listitem>
+ <para>Pointer to the characters.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->string.hasfillp</literal></term>
+ <listitem>
+ <para>True if <literal>x->string.fillp</literal> can be smaller than <literal>x->string.dim</literal>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>make_simple_string</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>make_simple_string</function> (<type>char</type> <varname>*</varname><varname>s</varname>)</screen>
+ <screen><indexterm role="fn"><primary>make_string_copy</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>make_string_copy</function> (<type>char</type> <varname>*</varname><varname>s</varname>)</screen>
+ <para>Both routines build a lisp string from a C string. <literal>make_string_copy</literal>
+ allocates new space and copies the content of the string to
+ it. <literal>make_simple_string</literal> simply uses the memory pointed by <replaceable>s</replaceable>, which
+ should not be deallocated. Both routines use <literal>strlen</literal> to calculate the
+ length of the string.</para>
+ </blockquote>
+ </sect1>
+
+ <sect1 label="3.7" xml:id="Bitvectors">
+ <title>Bitvectors</title>
+ </sect1>
+
+ <sect1 label="3.8" xml:id="Streams">
+ <title>Streams</title>
+ </sect1>
+
+ <sect1 label="3.9" xml:id="Structures">
+ <title>Structures</title>
+ </sect1>
+
+ <sect1 label="3.10" xml:id="Instances">
+ <title>Instances</title>
+ <!-- -->
+ </sect1>
+
+ <sect1 label="3.11" xml:id="Bytecodes">
+ <title>Bytecodes</title>
+ <para>A bytecodes object is a lisp object with a piece of code that can be
+ interpreted. The objects of type <literal>t_bytecode</literal> are implicitly constructed
+ by a call to <literal>eval</literal>, but can also be explicitly constructed with the
+ <literal>make_lambda</literal> function.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>cl_safe_eval</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>cl_safe_eval</function> (<type>cl_object</type> <varname>form</varname>, <type>cl_object</type> <varname>env</varname>, <type>cl_object</type> <varname>err_value</varname></screen>
+ <screen><indexterm role="fn"><primary>cl_eval</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>cl_eval</function> (<type>cl_object</type> <varname>form</varname>)</screen>
+ <para><literal>cl_safe_eval</literal> evaluates <replaceable>form</replaceable> in the lexical environment <replaceable>env</replaceable>,
+ which can be <replaceable>nil</replaceable>. Before evaluating it, the expression <replaceable>form</replaceable> must
+ be bytecompiled. <literal>cl_eval</literal> is the equivalent of <literal>cl_safe_eval</literal> but
+ without environment and with <replaceable>err_value</replaceable> set to <replaceable>nil</replaceable>. It exists only
+ for compatibility with previous versions.</para>
+ <screen>
+ cl_object form = c_string_to_object("(print 1)");
+ cl_safe_eval(form,Cnil);
+ cl_safe_eval(form, Cnil);
+ </screen>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>si_make_lambda</primary></indexterm>— Function: <returnvalue>cl_object</returnvalue> <function>si_make_lambda</function> (<type>cl_object</type> <varname>name</varname>, <type>cl_object</type> <varname>def</varname>)</screen>
+ <para>Builds an interpreted lisp function with name given by the symbol <replaceable>name</replaceable>
+ and body given by <replaceable>def</replaceable>. For instance, we would achieve the equivalent of</para>
+ <programlisting>
+ (funcall #'(lambda (x y) (block foo (+ x y)))
+ 1 2)
+ </programlisting>
+ <para role="continues">with the following code</para>
+ <screen>
+ cl_object def = c_string_to_object("((x y) (+ x y))");
+ cl_object name = _intern("foo")
+ cl_object fun = si_make_lambda(name, def);
+ return funcall(fun, MAKE_FIXNUM(1), MAKE_FIXNUM(2));
+ </screen>
+ <para role="continues">Notice that <literal>si_safe_lambda</literal> performs a bytecodes compilation
+ of the definition and thus it may signal some errors. Such errors are not
+ handled by the routine itself you might consider using <literal>cl_safe_eval</literal>
+ or <literal>cl_eval</literal> instead:</para>
+ <screen>
+ cl_object def = c_string_to_object("#'(lambda-block foo (x y) (+ x y))");
+ cl_object fun = cl_eval(def);
+ return funcall(fun, MAKE_FIXNUM(1), MAKE_FIXNUM(2));
+ </screen>
+ </blockquote>
+ <!-- -->
+ </sect1>
+ </section>
+
+ <section xml:id="The-interpreter">
+ <title>The interpreter</title>
+ <sect1 label="4.1" xml:id="ECL-stacks">
+ <title>&ECL; stacks</title>
+ <para>&ECL; uses the following stacks:</para>
+ <variablelist>
+ <varlistentry>
+ <term>Frame Stack</term>
+ <listitem>
+ <para>consisting of catch, block, tagbody frames</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Bind Stack</term>
+ <listitem>
+ <para>for shallow binding of dynamic variables</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Interpreter Stack</term>
+ <listitem>
+ <para>acts as a Forth data stack, keeping intermediate arguments to
+ interpreted functions, plus a history of called functions.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>C Control Stack</term>
+ <listitem>
+ <para>used for arguments/values passing, typed lexical variables,
+ temporary values, and function invocation.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 label="4.2" xml:id="Procedure-Call-Conventions">
+ <title>Procedure Call Conventions</title>
+ <para>&ECL; employs standard C calling conventions to achieve efficiency and
+ interoperability with other languages.
+ Each Lisp function is implemented as a C function which takes as many
+ argument as the Lisp original plus one additional integer argument
+ which holds the number of actual arguments. The function sets <literal>NValues</literal>
+ to the number of Lisp values produced, it returns the first one and the
+ remaining ones are kept in a global (per thread) array (<literal>VALUES</literal>).</para>
+ <para>To show the argument/value passing mechanism, here we list the actual
+ code for the Common-Lisp function <literal>cons</literal>.</para>
+ <screen>
+ cl_cons(int narg, object car, object cdr)
+ { object x;
+ check_arg(2);
+ x = alloc_object(t_cons);
+ CAR(x) = car;
+ CDR(x) = cdr;
+ NValues = 1;
+ return x;
+ }
+ </screen>
+ <para>&ECL; adopts the convention that the name of a function that implements a
+ Common-Lisp function begins with a short package name (<literal>cl</literal> for COMMON-LISP,
+ <literal>si</literal> for SYSTEM, etc), followed by <literal>L</literal>, and followed by the name of
+ the Common-Lisp function. (Strictly speaking, `<literal>-</literal>' and `<literal>*</literal>' in the
+ Common-Lisp function name are replaced by `<literal>_</literal>' and `<literal>A</literal>', respectively,
+ to obey the syntax of C.)</para>
+ <para><literal>check_arg(2)</literal> in the code of <literal>cl_cons</literal> checks that exactly two
+ arguments are supplied to <literal>cons</literal>. That is, it checks that <literal>narg</literal> is
+ 2, and otherwise, it causes an error. <literal>allocate_object(t_cons)</literal> allocates
+ a cons cell in the heap and returns the pointer to the cell. After the
+ <literal>CAR</literal> and the <literal>CDR</literal> fields of the cell are set, the cell pointer is
+ returned directly. The number assigned to NValues set by the function (1 in
+ this case) represents the number of values of the function.</para>
+ <para>In general, if one is to play with the C kernel of &ECL; there is no need to
+ know about all these conventions. There is a preprocessor that takes care of
+ the details, by using a lisp representation of the statements that output
+ values, and of the function definitions. For instance, the actual source code
+ for <literal>cl_cons</literal> in <filename>src/c/lists.d</filename></para>
+ <screen>
+ @(defun cons (car cdr)
+ @
+ @(return CONS(car, cdr))
+ @)
+ </screen>
+ </sect1>
+
+ <sect1 label="4.3" xml:id="The-lexical-environment">
+ <title>The lexical environment</title>
+ <para>The &ECL; interpreter uses two A-lists (Association lists) to
+ represent lexical environments.</para>
+ <itemizedlist mark="bullet">
+ <listitem>
+ <para>One for variable bindings</para>
+ </listitem>
+ <listitem>
+ <para>One for local function/macro/tag/block bindings</para>
+ </listitem>
+ </itemizedlist>
+ <para>When a function closure is created, the current two A-lists are
+ saved in the closure along with the lambda expression. Later, when the
+ closure is invoked, the saved A-lists are
+ used to recover the lexical environment.</para>
+ </sect1>
+
+ <sect1 label="4.4" xml:id="The-interpreter-stack">
+ <title>The interpreter stack</title>
+ <para>The bytecodes interpreter uses a stack of its own to save and restore values
+ from intermediate calculations. This Forth-like data stack is also used in
+ other parts of the C kernel for various purposes, such as saving compiled code,
+ keeping arguments to FORMAT, etc.</para>
+ <para>However, one of the most important roles of the Interpreter Stack is to keep a
+ log of the functions which are called during the execution of bytecodes. For
+ each function invoked, the interpreter keeps three lisp objects on the stack:</para>
+ <screen><![CDATA[
+ +----------+------------------------------------------------+
+ | function | lexical environment | index to previous record |
+ +----------+---------------------+--------------------------+
+ ]]></screen>
+ <para>The first item is the object which is funcalled. It can be a bytecodes object,
+ a compiled function or a generic function. In the last two cases the lexical
+ environment is just NIL. In the first case, the second item on the stack is
+ the lexical environment on which the code is executed. Each of these records
+ are popped out of the stack after function invocation.</para>
+ <para>Let us see how these invocation records are used for debugging.<screen>
+ >(defun fact (x) ;;; Wrong definition of the
+ (if (= x 0) ;;; factorial function.
+ one ;;; one should be 1.
+ (* x (fact (1- x)))))
+ FACT
+
+ >(fact 3) ;;; Tries 3!
+ Error: The variable ONE is unbound.
+ Error signalled by IF.
+ Broken at IF.
+ >>:b ;;; Backtrace.
+ Backtrace: eval > fact > if > fact > if > fact > if > fact > IF
+ ;;; Currently at the last IF.
+ >>:h ;;; Help.
+
+ Break commands:
+ :q(uit) Return to some previous break level.
+ :pop Pop to previous break level.
+ :c(ontinue) Continue execution.
+ :b(acktrace) Print backtrace.
+ :f(unction) Show current function.
+ :p(revious) Go to previous function.
+ :n(ext) Go to next function.
+ :g(o) Go to next function.
+ :fs Search forward for function.
+ :bs Search backward for function.
+ :v(ariables) Show local variables, functions, blocks, and tags.
+ :l(ocal) Return the nth local value on the stack.
+ :hide Hide function.
+ :unhide Unhide function.
+ :hp Hide package.
+ :unhp Unhide package.
+ :unhide-all Unhide all variables and packages.
+ :bds Show binding stack.
+ :m(essage) Show error message.
+ :hs Help stack.
+ Top level commands:
+ :cf Compile file.
+ :exit or ^D Exit Lisp.
+ :ld Load file.
+ :step Single step form.
+ :tr(ace) Trace function.
+ :untr(ace) Untrace function.
+
+ Help commands:
+ :apropos Apropos.
+ :doc(ument) Document.
+ :h(elp) or ? Help. Type ":help help" for more information.
+
+ >>:p ;;; Move to the last call of FACT.
+ Broken at IF.
+
+ >>:b
+ Backtrace: eval > fact > if > fact > if > fact > if > FACT > if
+ ;;; Now at the last FACT.
+ >>:v ;;; The environment at the last call
+ Local variables: ;;; to FACT is recovered.
+ X: 0 ;;; X is the only bound variable.
+ Block names: FACT. ;;; The block FACT is established.
+
+ >>x
+ 0 ;;; The value of x is 0.
+
+ >>(return-from fact 1) ;;; Return from the last call of
+ 6 ;;; FACT with the value of 0.
+ ;;; The execution is resumed and
+ > ;;; the value 6 is returned.
+ ;;; Again at the top-level loop.
+ </screen></para>
+ <!-- -->
+ </sect1>
+ </section>
+
+ <section xml:id="The-compiler">
+ <title>The compiler</title>
+ <sect1 label="5.1" xml:id="The-compiler-translates-to-C">
+ <title>The compiler translates to C</title>
+ <para>The &ECL; compiler is essentially a translator from Common-Lisp to C. Given
+ a Lisp source file, the compiler first generates three intermediate
+ files:</para>
+ <itemizedlist mark="bullet">
+ <listitem>
+ <para>a C-file which consists of the C version of the Lisp program</para>
+ </listitem>
+ <listitem>
+ <para>an H-file which consists of declarations referenced in the C-file</para>
+ </listitem>
+ <listitem>
+ <para>a Data-file which consists of Lisp data to be used at load time</para>
+ </listitem>
+ </itemizedlist>
+ <para>The &ECL; compiler then invokes the C compiler to compile the
+ C-file into an object file. Finally, the contents of the Data-file is
+ appended to the object file to make a <emphasis>Fasl-file</emphasis>. The generated
+ Fasl-file can be loaded into the &ECL; system by the Common-Lisp
+ function <literal>load</literal>. By default, the three intermediate files are
+ deleted after the compilation, but, if asked, the compiler leaves
+ them.</para>
+ <para>The merits of the use of C as the intermediate language are:</para>
+ <itemizedlist mark="-">
+ <listitem>
+ <para>The &ECL; compiler is highly portable.</para>
+ </listitem>
+ <listitem>
+ <para>Cross compilation is possible, because the contents of the
+ intermediate files are common to all versions of &ECL;. For example,
+ one can compile his or her Lisp program by the &ECL; compiler on
+ a Sun, bring the intermediate files to DOS, compile the C-file with
+ the gcc compiler under DOS, and then append the Data-file to the object
+ file. This procedure generates the Fasl-file for the &ECL; system on
+ DOS. This kind of cross compilation makes it easier to port &ECL;.</para>
+ </listitem>
+ <listitem>
+ <para>Hardware-dependent optimizations such as register allocations
+ are done by the C compiler.</para>
+ </listitem>
+ </itemizedlist>
+ <para>The demerits are:</para>
+ <itemizedlist mark="-">
+ <listitem>
+ <para>At those sites where no C compiler is available,
+ the users cannot compile their Lisp programs.</para>
+ </listitem>
+ <listitem>
+ <para>The compilation time is long. 70% to 80% of the
+ compilation time is used by the C compiler. The &ECL; compiler is
+ therefore slower than compiler generating machine code directly.</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 label="5.2" xml:id="The-compiler-mimics-human-C-programmer">
+ <title>The compiler mimics human C programmer</title>
+ <para>The format of the intermediate C code generated by the &ECL; compiler is the
+ same as the hand-coded C code of the &ECL; source programs. For example,
+ supposing that the Lisp source file contains the
+ following function definition:</para>
+ <programlisting>
+ (defvar *delta* 2)
+ (defun add1 (x) (+ *delta* x))
+ </programlisting>
+ <para role="continues">The compiler generates the following intermediate C code.</para>
+ <screen>
+ /* function definition for ADD1 */
+ static cl_object L1(cl_object V1)
+ { VT2 VLEX2 CLSR2
+ cl_object value0;
+ value0=number_plus(symbol_value(VV[0]),V1); NVALUES=1;
+ return value0;
+ }
+ /* initialization of this module */
+ void init_CODE(cl_object flag)
+ { VT1 CLSR1
+ cl_object value0;
+ if (!FIXNUMP(flag)){
+ Cblock=flag;
+ #ifndef ECL_DYNAMIC_VV
+ flag->cblock.data = VV;
+ #endif
+ flag->cblock.self_destruct=0;
+ flag->cblock.data_size = VM;
+ flag->cblock.data_text = compiler_data_text;
+ flag->cblock.data_text_size = compiler_data_text_size;
+ return;}
+ #ifdef ECL_DYNAMIC_VV
+ VV = Cblock->cblock.data;
+ #endif
+ T0= MAKE_FIXNUM(2);
+ si_Xmake_special(VV[0])
+ if(SYM_VAL(T0)!=OBJNULL) cl_setq(VV[0],T0);
+ cl_def_c_function(VV[1],(void*)L1,1);
+ }
+ </screen>
+ <para>The C function <literal>L1</literal> implements the Lisp function <literal>add1</literal>.
+ This relation is established by <literal>cl_def_c_function</literal> in the
+ initialization function <literal>init_CODE</literal>, which is invoked at load
+ time. There, the vector <literal>VV</literal> consists of Lisp objects;
+ <literal>VV[0]</literal> and <literal>VV[1]</literal> in this example hold the Lisp symbols
+ <literal>*delta*</literal> and <literal>add1</literal>. <literal>VM</literal> in the definition of
+ <literal>L1</literal> is a C macro declared in the corresponding H-file. The
+ actual value of <literal>VM</literal> is the number of value stack locations used
+ by this module, i.e., 2 in this example. Thus the following macro
+ definition is found in the H-file.</para>
+ <screen>
+ #define VM 2
+ </screen>
+ </sect1>
+
+ <sect1 label="5.3" xml:id="Implementation-of-Compiled-Closures">
+ <title>Implementation of Compiled Closures</title>
+ <para>The &ECL; compiler takes two passes before it invokes the C
+ compiler. The major role of the first pass is to detect function
+ closures and to detect, for each function closure, those lexical
+ objects (i.e., lexical variable, local function definitions, tags, and
+ block-names) to be enclosed within the closure. This check must be
+ done before the C code generation in the second pass, because lexical
+ objects to be enclosed in function closures are treated in a different
+ way from those not enclosed.</para>
+ <para>Ordinarily, lexical variables in a compiled function <emphasis>f</emphasis>
+ are allocated on the C stack. However, if a lexical variable is
+ to be enclosed in function closures, it is allocated on a list, called
+ the “environment list”, which is local to <emphasis>f</emphasis>. In addition, a
+ local variable is created which points to the lexical
+ variable's location (within the environment list), so that
+ the variable may be accessed through an indirection rather than by list
+ traversal.</para>
+ <para>The environment list is a pushdown list: It is empty when <emphasis>f</emphasis> is called.
+ An element is pushed on the environment list when a variable to be enclosed in
+ closures is bound, and is popped when the binding is no more in effect. That
+ is, at any moment during execution of <emphasis>f</emphasis>, the environment list contains
+ those lexical variables whose binding is still in effect and which should be
+ enclosed in closures. When a compiled closure is created during execution of
+ <emphasis>f</emphasis>, the compiled code for the closure is coupled with the environment
+ list at that moment to form the compiled closure.</para>
+ <para>Later, when the compiled closure is invoked, a pointer is set up to each
+ lexical variable in the environment list, so that each object may be referenced
+ through a memory indirection.</para>
+ <para>Let us see an example. Suppose the following function has been compiled.</para>
+ <programlisting>
+ (defun foo (x)
+ (let ((a #'(lambda () (incf x)))
+ (y x))
+ (values a #'(lambda () (incf x y)))))
+ </programlisting>
+ <para><literal>foo</literal> returns two compiled closures. The first closure increments <replaceable>x</replaceable>
+ by one, whereas the second closure increments <replaceable>x</replaceable> by the initial value of
+ <replaceable>x</replaceable>. Both closures return the incremented value of <replaceable>x</replaceable>.</para>
+ <para><screen>
+ >(multiple-value-setq (f g) (foo 10))
+ #<compiled-closure nil>
+
+ >(funcall f)
+ 11
+
+ >(funcall g)
+ 21
+
+ >
+ </screen></para>
+ <para>After this, the two compiled closures look like:</para>
+ <screen><![CDATA[
+ second closure y: x:
+ |-------|------| |-------|------| |------|------|
+ | ** | --|----->| 10 | --|------>| 21 | nil |
+ |-------|------| |-------|------| |------|------|
+ ^
+ first closure |
+ |-------|------| |
+ | * | --|----------|
+ |-------|------|
+
+ * : address of the compiled code for #'(lambda () (incf x))
+ ** : address of the compiled code for #'(lambda () (incf x y))
+ ]]></screen>
+ </sect1>
+
+ <sect1 label="5.4" xml:id="Use-of-Declarations-to-Improve-Efficiency">
+ <title>Use of Declarations to Improve Efficiency</title>
+ <para>Declarations, especially type and function declarations,
+ increase the efficiency of the compiled code. For example, for the
+ following Lisp source file, with two Common-Lisp declarations added,</para>
+ <programlisting>
+ (eval-when (compile)
+ (proclaim '(function tak (fixnum fixnum fixnum) fixnum))
+
+ (defun tak (x y z)
+ (declare (fixnum x y z))
+ (if (not (< y x))
+ z
+ (tak (tak (1- x) y z)
+ (tak (1- y) z x)
+ (tak (1- z) x y))))
+ </programlisting>
+ <para>The compiler generates the following C code:</para>
+ <screen>
+ /* local entry for function TAK */
+ static int LI1(register int V1,register int V2,register int V3)
+ { VT3 VLEX3 CLSR3
+ TTL:
+ if (V2 < V1) {
+ goto L2;}
+ return(V3);
+ L2:
+ { int V5;
+ V5 = LI1((V1)-1,V2,V3);
+ { int V6;
+ V6 = LI1((V2)-1,V3,V1);
+ V3 = LI1((V3)-1,V1,V2);
+ V2 = V6;
+ V1 = V5;}}
+ goto TTL;
+ ;;; Note: Tail-recursive call of TAK was replaced by iteration.
+ }
+ </screen>
+ </sect1>
+
+ <sect1 label="5.5" xml:id="Inspecting-generated-C-code">
+ <title>Inspecting generated C code</title>
+ <para>Common-Lisp defines a function disassemble, which is
+ supposed to disassemble a compiled function and to display the
+ assembler code. According to <emphasis>Common-Lisp: The Language</emphasis>,</para>
+
+ <para><emphasis>This is primary useful for debugging the compiler</emphasis>, ..\\</para>
+ <!-- FIXME: Actually disassemble shows bytecode -->
+ <para>This is, however, <emphasis>useless</emphasis> in our case, because we are
+ not concerned with assembly language. Rather, we are interested in
+ the C code generated by the &ECL; compiler. Thus the disassemble
+ function in &ECL; accepts not-yet-compiled functions only and displays
+ the translated C code.</para>
+ <para><screen>
+ > (defun add1 (x) (1+ x))
+ ADD1
+ > (disassemble *)
+ ;;; Compiling (DEFUN ADD1 ...).
+ ;;; Emitting code for ADD1.
+
+ /* function definition for ADD1 */
+ static L1(int narg, object V1)
+ { VT3 VLEX3 CLSR3
+ TTL:
+ VALUES(0) = one_plus((V1));
+ RETURN(1);
+ }
+ </screen></para>
+ </sect1>
+
+ <sect1 label="5.6" xml:id="Embedding-C-code">
+ <title>Embedding C code in lisp source</title>
+ <para>There are several mechanism to integrate C code within &ECL;, but
+ everything is built around two functions that allow the user to embed
+ arbitrary C/C++ code into Lisp source code.</para>
+ <para>The two mechanisms are the <literal>Clines</literal> and the <literal>c-inline</literal> special
+ forms. The first one permits to insert code in the intermediate C/C++ file
+ generated by the &ECL; compiler. Such a form outputs no value and takes
+ no arguments, except a series of strings which are inserted literally,
+ such as <literal>#include</literal> or <literal>#define</literal> statements, function definitions, etc.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>Clines</primary></indexterm>— Macro: <function>Clines</function> <varname>{</varname><varname>{</varname><varname>string</varname><varname>}</varname><varname>*</varname><varname>}</varname></screen>
+ <para>When the &ECL; compiler encounters a macro form <literal>(Clines <replaceable>string1
+ ... stringn</replaceable>)</literal>, it simply outputs the <replaceable>strings</replaceable> into the c-file. The
+ arguments are not evaluated and each argument must be a string. Each
+ <replaceable>string</replaceable> may consist of any number of lines, and separate lines in the
+ <replaceable>string</replaceable> are placed in separate lines in the c-file. In addition, each
+ <replaceable>string</replaceable> opens a fresh line in the c-file, i.e., the first character in the
+ <replaceable>string</replaceable> is placed at the first column of a line. Therefore, C-language
+ preprocessor commands such as <literal>#define</literal> and <literal>#include</literal> will be
+ recognized as such by the C compiler, if the ' # ' sign appears as the first
+ character of the <replaceable>string</replaceable> or as the first character of a line within the
+ <replaceable>string</replaceable>.</para>
+ <para>When interpreted, a <literal>Clines</literal> macro form expands to ().</para>
+ </blockquote>
+ <programlisting>(use-package "FFI")
+
+ (Clines
+ " int tak(x, y, z) "
+ " int x, y, z; "
+ " { if (y >= x) return(z); "
+ " else return(tak(tak(x-1, y, z), "
+ " tak(y-1, z, x), "
+ " tak(z-1, x, y))); "
+ " } "
+ )
+
+ (defun tak (x y z)
+ (c-inline (x y z) (:int :int :int) :int
+ "tak(#0,#1,#2)" :one-liner t))
+ </programlisting>
+ <para>The second mechanism, which you already appreciate in the example above, is the
+ <literal>c-inline</literal> special form. This powerful method allows the user to insert C
+ code which is evaluated, and which can accept values and return values from and
+ to the Lisp world, with an automatic convertion taking place in both directions.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>c-inline</primary></indexterm>— Macro: <function>c-inline</function> <varname>{</varname><varname>args-list</varname> <varname>arg-C-types</varname> <varname>output-C-type</varname> <varname>C-expr</varname> <varname>&key</varname> (<varname>side-effects</varname> <varname><literal>T</literal></varname>) (<varname>one-liner</varname> <varname><literal>T</literal></varname>)<varname>}</varname></screen>
+ <para><literal>c-inline</literal> is a special form that can only be used in compiled
+ code. For all purposes it behaves as a Lisp form, which takes the
+ arguments given in <replaceable>args-list</replaceable> and produces a single value. Behind
+ the curtains, the arguments of <replaceable>args-list</replaceable> (which can be any valid
+ Lisp form) are coerced to the the C types given in <replaceable>arg-C-types</replaceable>,
+ passed to the C expression <replaceable>C-expr</replaceable>, and coerced back to Lisp
+ using the C type <replaceable>output-C-type</replaceable> as a guide. Multiple return
+ values can be returned by setting <replaceable>output-C-type</replaceable> to <literal>(values
+ type-1 type-2 ...)</literal>.</para>
+ <para><replaceable>C-expr</replaceable> is a string containing C code and maybe some special
+ escape codes. First, the arguments of the form may be retrieved as
+ <literal>#0</literal>, <literal>#1</literal>, etc. Second, if the <literal>c-inline</literal> form is a
+ one-line C expression (That is, <replaceable>one-liner</replaceable> is true), then the
+ whole expression is interpreted as the output value. But if the code,
+ on the other hand, is a multiline expression (<replaceable>one-liner</replaceable> is
+ false), the form has to be output using <literal>@(return)
+ =...</literal>. Multiple values are returned as <literal>@(return 0)=... ;
+ @(return 1)=...;</literal>. Finally, Lisp constants may be used in the C code
+ making use of the prefix <literal>@</literal>.</para>
+ <programlisting>
+ (use-package "FFI")
+
+ (Clines "
+ #include <math.h>
+
+ double foo (double x, double y) {
+ return sinh(x) * y;
+ }")
+
+ (defvar *a*
+ (c-inline (1.23) (:double) :double
+ "foo(#0,1.44)"
+ :side-effects nil
+ :one-liner t))
+
+ (defvar *b*
+ (c-inline (1.23) (:double) :double
+ "{cl_object x = symbol_value(@*a*);
+ @(return) = foo(#0,object_to_float(x));}"
+ :side-effects nil
+ :one-liner nil))
+ </programlisting>
+ </blockquote>
+ </sect1>
+
+ <sect1 label="5.7" xml:id="The-C-language-interface">
+ <title>The C language interface</title>
+ <para>Using these special forms <literal>clines</literal> and <literal>c-inline</literal>, plus the ability to
+ handle pointers to foreign data, we have built a rather complete FFI for
+ interfacing with the C world. This interface is compatible with the UFFI
+ specification, which can be found in the web. We recommend you to grab the
+ documentation from this package and read it carefully. All examples should
+ run unmodified under &ECL; (Of course, you do not need to download UFFI
+ itself, as everything is already implemented in &ECL;.</para>
+ <para>However, because &ECL; provides some additional functionality which escapes the
+ UFFI, and also for compatibility with older versions of the &ECL; environment,
+ we provide additional toplevel forms, which are listed in the next section.</para>
+ </sect1>
+
+ <sect1 label="5.8" xml:id="The-old-C-language-interface">
+ <title>The old C language interface</title>
+ <para>In this section we list several macros and toplevel forms which are provided
+ either for convenience or for compatibility with older versions of &ECL;.
+ You should avoid using them when the UFFI-compatible interface provides
+ similar functionality.</para>
+ <para>We define some terminology here which is used throughout this Section. A
+ <emphasis>C-id</emphasis> is either a Lisp string consisting of a valid C-language
+ identifier, or a Lisp symbol whose print-name, with all its alphabetic
+ characters turned into lower case, is a valid C identifier. Thus the symbol
+ <literal>foo</literal> is equivalent to the string <literal>"foo"</literal> when used as a C-id.
+ Similarly, a <emphasis>C-expr</emphasis> is a string that may be regarded as a
+ C-language expression. A <emphasis>C-type</emphasis> is one of the Lisp symbols
+ <literal>:int, :char, :float, :double,...</literal> and <literal>:object</literal>.
+ Each corresponds to a data type in the C language; <literal>:object</literal> is
+ the type of Lisp object and other C-types are primitive data types in C.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>defentry</primary></indexterm>— Macro: <function>defentry</function> <varname>{</varname><varname>function</varname> <varname>parameter-list</varname> <varname>C-function</varname><varname>}</varname></screen>
+ <para><literal>defentry</literal> defines a Lisp function whose body consists of the calling
+ sequence to a C-language function. <replaceable>function</replaceable> is the name of the Lisp
+ function to be defined, and <replaceable>C-function</replaceable> specifies the C function to be
+ invoked. <replaceable>C-function</replaceable> must be either a list <literal>(<replaceable>type C-id</replaceable>)</literal> or
+ <replaceable>C-id</replaceable>, where <replaceable>type</replaceable> and <replaceable>C-id</replaceable> are the type and the name of the C
+ function. <replaceable>type</replaceable> must be a C-type or the symbol <literal>void</literal> which means
+ that the C function returns no value. <literal>(object <replaceable>C-id</replaceable>)</literal> may be
+ abbreviated as <replaceable>C-id</replaceable>. <replaceable>parameter-list</replaceable> is a list of C-types for the
+ parameters of the C function. For example, the following <literal>defentry</literal> form
+ defines a Lisp function <literal>tak</literal> from which the C function <literal>tak</literal> above
+ is called.</para>
+ </blockquote>
+ <programlisting>(defentry tak (:int :int :int) (:int tak))
+ </programlisting>
+ <para>The Lisp function <literal>tak</literal> defined by this <literal>defentry</literal> form requires
+ three arguments. The arguments are converted to <literal>int</literal> values before they
+ are passed to the C function. On return from the C function, the returned
+ <literal>int</literal> value is converted to a Lisp integer (actually a fixnum) and this
+ fixnum will be returned as the value of the Lisp function. See below for type
+ conversion between Lisp and the C language.</para>
+ <para>A <literal>defentry</literal> form is treated in the above way only when it appears as a
+ top-level form of a Lisp source file. Otherwise, a <literal>defentry</literal> form
+ expands to ().</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>defla</primary></indexterm>— Macro: <function>defla</function> <varname>{</varname><varname>name</varname> <varname>lambda-list</varname> <varname>{</varname><varname>declaration</varname> <varname>|</varname> <varname>doc-string</varname><varname>}</varname><varname>*</varname><varname>}</varname></screen>
+ <para>When interpreted, <literal>defla</literal> is exactly the same as <literal>defun</literal>. That is,
+ <literal>(defla <replaceable>name lambda-list . body</replaceable>)</literal> expands to <literal>(defun <replaceable>name
+ lambda-list . body</replaceable>)</literal>. However, <literal>defla</literal> forms are completely ignored by
+ the compiler; no C-language code will be generated for <literal>defla</literal> forms. The
+ primary use of <literal>defla</literal> is to define a Lisp function in two ways within a
+ single Lisp source file; one in the C language and the other in Lisp.
+ <literal>defla</literal> is short for <emphasis>DEF</emphasis>ine <emphasis>L</emphasis>isp <emphasis>A</emphasis>lternative.</para>
+ </blockquote>
+ <para>Suppose you have a Lisp source file whose contents are:</para>
+ <programlisting>(use-package "FFI")
+
+ ;;; C version of TAK.
+ (Clines "
+
+ int tak(x, y, z)
+ int x, y, z;
+ { if (y >= x) return(z);
+ else return(tak(tak(x-1, y, z),
+ tak(y-1, z, x),
+ tak(z-1, x, y)));
+ }
+ "
+ )
+
+ ;;; TAK calls the C function tak defined above.
+ (defentry tak (:int :int :int) (:int tak))
+ ;;; The alternative Lisp definition of TAK.
+ (defla tak (x y z)
+ (if (>= y x)
+ z
+ (tak (tak (1- x) y z)
+ (tak (1- y) z x)
+ (tak (1- z) x y))))
+ </programlisting>
+ <para>When this file is loaded into &ECL;, the interpreter uses the Lisp version of
+ the <literal>tak</literal> definition. Once this file has been compiled, and when the
+ generated fasl file is loaded into &ECL;, a function call to <literal>tak</literal> is
+ actually the call to the C version of <literal>tak</literal>.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>defCbody</primary></indexterm>— Function: <function>defCbody</function> <varname>name args-types result-type C-expr</varname></screen>
+ <para>The &ECL; compiler produces a function named <replaceable>name</replaceable> with as many
+ arguments as <replaceable>arg-types</replaceable>. The <replaceable>C-expr</replaceable> is an arbitrary C expression
+ where the arguments to the function are denoted by <literal>#</para>
+ <replaceable>i</replaceable></literal>
+ <para>, where
+ <literal></para>
+ <replaceable>i</replaceable></literal>
+ <para>is the integer corresponding to the argument position. The
+ <replaceable>args-types</replaceable> is the list of Common-Lisp types of the arguments to the function,
+ while <replaceable>result-type</replaceable> is the Common-Lisp type of the result. The actual arguments
+ are coerced to the required types before executing the <replaceable>C-expr</replaceable> and the
+ result is converted into a Lisp object. <literal>defCbody</literal> is ignored by the
+ interpreter.</para>
+ </blockquote>
+ <para>For example, the logical AND of two integers could be defined as:</para>
+ <programlisting>(defCbody logand (fixnum fixnum) fixnum "(#0) & (#1)")
+ </programlisting>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>definline</primary></indexterm>— Function: <function>definline</function> <varname>{</varname><varname>name</varname> <varname>args-types</varname> <varname>result-type</varname> <varname>C-expr</varname><varname>}</varname></screen>
+ <para><literal>definline</literal> behaves exactly as <literal>defCbody</literal>. Moreover, after a
+ <literal>definline</literal> definition has been supplied, the &ECL; compiler will expand
+ inline any call to function <replaceable>name</replaceable> into code corresponding to the C
+ language expression <replaceable>C-expr</replaceable>, provided that the actual arguments are of the
+ specified type. If the actual arguments cannot be coerced to those types, the
+ inline expansion is not performed. <literal>definline</literal> is ignored by the
+ interpreter.</para>
+ </blockquote>
+ <para>For example, a function to access the n-th byte of a string and return it as an
+ integer can be defined as follows:</para>
+ <programlisting>(definline aref-byte (string fixnum) fixnum
+ "(#0)->ust.ust_self[#1]")
+ </programlisting>
+ <para>The definitions of the C data structures used to represent \clisp objects can
+ be found in file <literal>ecl.h</literal> in the directory <literal>"src/h"</literal> of the source
+ distribution.</para>
+ <para>&ECL; converts a Lisp object into a C-language data by using the Common-Lisp
+ function <literal>coerce</literal>: For the C-type <literal>int</literal> (or <literal>char</literal>), the object
+ is first coerced to a Lisp integer and the least significant 32-bit (or 8-bit)
+ field is used as the C <literal>int</literal> (or <literal>char</literal>). For the C-type
+ <literal>float</literal> (or <literal>double</literal>), the object is coerced to a single-float (or a
+ double-float) and this value is used as the <literal>C float</literal> (or <literal>double</literal>).
+ Conversion from a C data into a Lisp object is obvious: <literal>C char, int,
+ float,</literal> and <literal>double</literal> become the equivalent Lisp <literal>character</literal>,
+ <literal>fixnum</literal>, <literal>single-float</literal>, and <literal>double-float</literal>, respectively.</para>
+ <para>Here we list the complete syntax of <literal>Clines</literal>, <literal>defentry</literal>,
+ <literal>definline</literal> and <literal>defCbody</literal> macro forms.</para>
+ <screen><![CDATA[
+ Clines-form:
+ (Clines @{string@}*)
+
+ defentry-form:
+ (defentry symbol (@{C-type@}*)
+ @{C-function-name | (@{C-type | void@} C-function-name)@})
+
+ defCbody-form:
+ (defCbody symbol (@{type@}*) type C-expr)
+
+ definline-form:
+ (defCbody symbol (@{type@}*) type C-expr)
+
+ C-function-name:
+ @{ string | symbol @}
+ C-expr:
+ string
+ C-type:
+ @{ object | int | char | float | double @}
+ ]]></screen>
+ <!-- -->
+ </sect1>
+ </section>
+
+ <section xml:id="The-Garbage-Collector">
+ <title>The Garbage Collector</title>
+ <para>Using &ECL; in existing application sometimes involves keeping Lisp
+ objects where the garbage collector normally cannot see them.</para>
+ <!-- FIXME: Complete this... -->
+ <!-- -->
+ </section>
+
+ <section xml:id="Porting-ECL">
+ <title>Porting &ECL;</title>
+ <para>To port &ECL; to a new architecture, the following steps are required:</para>
+ <orderedlist numeration="arabic">
+ <listitem>
+ <para>Ensure that the GNU Multiprecision library supports this machine.</para>
+ </listitem>
+ <listitem>
+ <para>Ensure that the Boehm-Weiser garbage collector is supported by that
+ architecture. Alternatively, port ECL's own garbage collector
+ <filename>src/c/alloc.d</filename> and <filename>src/c/gbc.d</filename> to that platform.</para>
+ </listitem>
+ <listitem>
+ <para>Fix <filename>src/aclocal.in</filename>, <filename>src/h/ecl.h</filename> and <filename>src/h/ecl-cmp.h</filename>
+ so that they supply flags for the new host machine.</para>
+ </listitem>
+ <listitem>
+ <para>Fix the machine dependent code in <filename>src/c/</filename>. The most critical
+ parts are in the <filename>unix*</filename> and <filename>thread*</filename> files.</para>
+ </listitem>
+ <listitem>
+ <para>Compile as in any other platform.</para>
+ </listitem>
+ <listitem>
+ <para>Run the tests and compare to the results of other platforms.</para>
+ </listitem>
+ </orderedlist>
+ </section>
+</chapter>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+-->
+</book>
--- /dev/null
+(require 'cl)
+
+(defvar ecl-search-string "")
+
+(defun query-replace-ecl-doc (from-string to-string &optional delimited start end)
+ (interactive (query-replace-read-args "Query replace" nil))
+ (let ((remaining (member (buffer-file-name (current-buffer)) ecl-doc-files)))
+ (dolist (i (or remaining ecl-doc-files))
+ (let ((b (find-buffer-visiting i)))
+ (unless (equal b (current-buffer))
+ (switch-to-buffer b)
+ (beginning-of-buffer)))
+ (perform-replace from-string to-string t nil delimited nil nil
+ start end))))
+
+(defun query-replace-regexp-ecl-doc (from-string to-string &optional delimited start end)
+ (interactive (query-replace-read-args "Query replace" nil))
+ (let ((remaining (member (buffer-file-name (current-buffer)) ecl-doc-files)))
+ (dolist (i (or remaining ecl-doc-files))
+ (let ((b (find-buffer-visiting i)))
+ (unless (equal b (current-buffer))
+ (switch-to-buffer b)
+ (beginning-of-buffer)))
+ (query-replace-regexp from-string to-string delimited start end))))
+
+(defun search-ecl-doc (string)
+ (interactive "sString: ")
+ (setq ecl-search-string string)
+ (let ((remaining (member (buffer-file-name (current-buffer)) ecl-doc-files)))
+ (dolist (i (or remaining ecl-doc-files))
+ (let ((b (find-buffer-visiting i)))
+ (unless (equal b (current-buffer))
+ (print b)
+ (switch-to-buffer b)
+ (beginning-of-buffer)))
+ (print '*)
+ (setq case-fold-search t)
+ (if (search-forward string nil t)
+ (return)))))
+
+(defun search-next-ecl-doc ()
+ (interactive)
+ (search-ecl-doc ecl-search-string))
+
+(defun back-to-emacs ()
+ (interactive)
+ (switch-to-buffer "emacs.el"))
+
+(defun next-ecl-doc ()
+ (interactive)
+ (let ((remaining (member (buffer-file-name (current-buffer)) ecl-doc-files)))
+ (when (cdr remaining)
+ (switch-to-buffer (find-buffer-visiting (cadr remaining))))))
+
+(global-set-key [?\M-p ?\C-i] 'back-to-emacs)
+(global-set-key [?\M-p ?\C-s] 'search-ecl-doc )
+(global-set-key [?\M-p ?\C-n] 'search-next-ecl-doc )
+(global-set-key [?\M-p ?\C-m] 'next-ecl-doc )
+(global-set-key [?\M-p ?\C-p] 'ecl-load-symbols)
+
+(setq auto-mode-alist (acons "\\.d\\'" 'c-mode auto-mode-alist))
+
+(setq ecl-doc-files
+ (mapcar (lambda (x)
+ ;(set-buffer "emacs.el")
+ (concat (subseq (buffer-file-name (current-buffer)) 0 -8) x))
+ '(
+"asdf.xmlf"
+"bibliography.xmlf"
+"clos.xmlf"
+"compiler.xmlf"
+"copyright.xmlf"
+"declarations.xmlf"
+"discarded.xml"
+"discarded.xmlf"
+"ecl.xml"
+"ecldev.xmlf"
+"embed.xmlf"
+"ffi.xmlf"
+"gc.xmlf"
+"internals.xmlf"
+"interpreter.xmlf"
+"intro.xmlf"
+"io.xmlf"
+"macros.xmlf"
+"memory.xmlf"
+"mop.xmlf"
+"mp.xmlf"
+"os.xmlf"
+"pde.xmlf"
+"preface.xmlf"
+"ref_c_arrays.xml"
+"ref_c_characters.xml"
+"ref_c_conditions.xml"
+"ref_c_conses.xml"
+"ref_c_data_flow.xml"
+"ref_c_environment.xml"
+"ref_c_evaluation.xml"
+"ref_c_filenames.xml"
+"ref_c_files.xml"
+"ref_c_hash_tables.xml"
+"ref_c_numbers.xml"
+"ref_c_objects.xml"
+"ref_c_packages.xml"
+"ref_c_printer.xml"
+"ref_c_reader.xml"
+"ref_c_sequences.xml"
+"ref_c_streams.xml"
+"ref_c_strings.xml"
+"ref_c_structures.xml"
+"ref_c_symbols.xml"
+"ref_c_system_construction.xml"
+"ref_c_types_and_classes.xml"
+"ref_embed.xmlf"
+"ref_memory.xmlf"
+"ref_mp.xmlf"
+"ref_os.xmlf"
+"ref_signals.xmlf"
+"schemas.xml"
+"signals.xmlf"
+"uffi/ref_aggregate.xml"
+"uffi/ref_declare.xml"
+"uffi/ref_func_libr.xml"
+"uffi/ref_object.xml"
+"uffi/ref_primitive.xml"
+"uffi/ref_string.xml"
+"uffi/schemas.xml"
+"ansi_arrays.xml"
+"ansi_characters.xml"
+"ansi_conses.xml"
+"ansi_data_flow.xml"
+"ansi_environment.xml"
+"ansi_evaluation.xml"
+"ansi_filenames.xml"
+"ansi_files.xml"
+"ansi_hash_tables.xml"
+"ansi_numbers.xml"
+"ansi_objects.xml"
+"ansi_overview.xml"
+"ansi_packages.xml"
+"ansi_printer.xml"
+"ansi_reader.xml"
+"ansi_sequences.xml"
+"ansi_streams.xml"
+"ansi_strings.xml"
+"ansi_structures.xml"
+"ansi_symbols.xml"
+"ansi_system_construction.xml"
+"ansi_types.xml"
+ )))
+
+(mapcar 'find-file ecl-doc-files)
+
+(defun ecl-doc-revert ()
+ (interactive)
+ (mapcar '(lambda (x) (let ((a (find-buffer-visiting x)))
+ (and a (switch-to-buffer a)
+ (revert-buffer t t))))
+ ecl-doc-files))
+
+(defun ecl-doc-save ()
+ (interactive)
+ (mapcar '(lambda (x) (let ((a (find-buffer-visiting x)))
+ (and a (switch-to-buffer a)
+ (save-buffer 0))))
+ ecl-doc-files))
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <chapter xml:id="ext.embed">
+ <title>Embedding &ECL;</title>
+
+ <section xml:id="ext.embed.intro">
+ <title>Introduction</title>
+
+ <para>TBD.</para>
+ </section>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ref_embed.xmlf" xpointer="ext.embed.dict"/>
+
+ </chapter>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ext.ffi">
+ <title>Foreign Function Interface</title>
+
+ <section xml:id="ext.ffi.what">
+ <title>What is a FFI?</title>
+
+ <para>A Foreign Function Interface, or &FFI; for short, is a means for a
+ programming language to interface with libraries written in other programming
+ languages, the <emphasis>foreign code</emphasis>. You will see this concept
+ most often being used in interpreted environments, such as Python, Ruby or
+ Lisp, where one wants to reuse the big number of libraries written in C
+ and C++ for dealing with graphical interfaces, networking, filesystems,
+ etc.</para>
+
+ <para>A FFI is made of at least three components:</para>
+ <variablelist>
+ <varlistentry>
+ <term>Foreign objects management</term>
+ <listitem><para>This is the data that the foreign code will use. A &FFI;
+ needs to provide means to buid and manipulate foreign data, with automatic
+ conversions to and from lisp data types whenever possible, and it also has
+ to deal with issues like garbage collection and
+ finalization.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Foreign code loader</term>
+ <listitem><para>To actually use a foreign routine, the code must reside in
+ memory. The process of loading this code and finding out the addresses of
+ the routines we want to use is normally done by an independent
+ component.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Foreign function invocation</term>
+ <listitem><para>This is the part of the &FFI; that deals with actually
+ calling the foreign routines we want to use. For that one typically has to
+ tell the &FFI; what are the arguments that these routines expect, what are
+ the calling conventions and where are these routines to be
+ found.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>On top of these components sits a higher level interface written
+ entirely in lisp, with which you will actually declare and use foreign
+ variables, functions and libraries. In the following sections we describe
+ both the details of the low-level components (<xref linkend="ext.ffi.dffi"/>,
+ <xref linkend="ext.ffi.objects"/>), and of the higher level interface (<xref
+ linkend="ext.ffi.uffi.and.cffi"/>). It is highly recommended that you read
+ <emphasis>all</emphasis> sections.</para>
+ </section>
+
+ <section xml:id="ext.ffi.dffi">
+ <title>Two kinds of FFI</title>
+
+ <para>&ECL; allows for two different appraoches when building a &FFI;. Both
+ approaches have a different implementation philosophy and affect the places
+ where you can use the &FFI; and how.
+ <variablelist>
+ <varlistentry>
+ <term>Static &FFI;</term>
+ <listitem><para>For every foreign function and variable you might need to
+ use, a wrapper is automatically written in C with the help of <xref
+ linkend="ref.c-inline"/>. These wrappers are compiled using an ordinary C
+ compiler and linked against both the foreign libraries you want to use and
+ against the &ECL; library. The result is a &FASL; file that can be loaded
+ from &ECL; and where the wrappers appear as ordinary lisp functions and
+ variables that the user may directly invoked.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Dynamic &FFI;</term>
+ <listitem><para>First of all, the foreign libraries are loaded in memory
+ using the facilities of the operating system. Similar routines are used to
+ find out and register the memory location of all the functions and
+ variables we want to use. Finally, when actually accessing these functions,
+ a little piece of assembly code does the job of translating the lisp data
+ into foreign objects, storing the arguments in the stack and in CPU
+ registers, calling the function and converting back the output of the
+ function to lisp.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <figure float="1" xml:id="fig.ffi">
+ <title>FFI components</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata align="center" fileref="figures/ffi.png"
+ format="PNG" width="300px"/>
+ </imageobject>
+ </mediaobject>
+ </figure>As you see, the first approach uses rather portable technices based
+ on a programming language (C, C++) which is strongly supported by the
+ operating system. The conversion of data is performed calling routines in the
+ &ECL; library and we need not care about the precise details (organizing the
+ stack, CPU registers, etc) when calling a function: the compiler does this
+ for us.</para>
+
+ <para>On the other hand, the dynamic approach allows us to choose the
+ libraries we load at any time, look for the functions and invoke them even
+ from the toplevel, but it relies on unportable techniques and requires from
+ us, the developers of &ECL;, to know very well both the assembly code of the
+ machine &ECL; runs on and the calling conventions of that particular
+ operating system.</para>
+
+ <para>&ECL; currently supports the static method on all platforms, and the
+ dynamical one a few of the most popular ones, shown in <xref
+ linkend="table.dffi"/>. You can test if your copy of &ECL; was built with
+ DFFI by inspecting whether the symbol <symbol>:DFFI</symbol> is present in
+ the list from variable <symbol>*FEATURES*</symbol>.</para>
+
+ <table xml:id="table.dffi">
+ <title>DFFI support</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Architecture</entry>
+ <entry>Support</entry>
+ <entry>Operating systems</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Intel x86 32 bits</entry>
+ <entry>Complete</entry>
+ <entry>Any with SysV ABI (Linux, BSD), Windows, OS X</entry>
+ </row>
+ <row>
+ <entry>Intel x86 64 bits</entry>
+ <entry>In progress</entry>
+ <entry>SysV ABI</entry>
+ </row>
+ <row>
+ <entry>PowerPC 32 bits</entry>
+ <entry>In progress</entry>
+ <entry>OS X</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section xml:id="ext.ffi.objects">
+ <title>Foreign objects</title>
+
+ <para>While the foreign function invocation protocols differ strongly between
+ platforms and implementations, foreign objects are pretty easy to handle
+ portably. For &ECL;, a foreign object is just a bunch of bytes stored in
+ memory. The lisp object for a foreign object encapsulates several bits of
+ information:
+ <itemizedlist>
+ <listitem><para>A list or a symbol specifying the C type of the
+ object.</para></listitem>
+ <listitem><para>The pointer to the region of memory where data is
+ stored.</para></listitem>
+ <listitem><para>A flag determining whether &ECL; can automatically manage
+ that piece of memory and deallocated when no longer in
+ use.</para></listitem>
+ </itemizedlist></para>
+
+ <para>A foreign object may contain many different kinds of data: integers,
+ floating point numbers, C structures, unions, etc. The actual type of the
+ object is stored in a list or a symbol which is understood by the higher
+ level interface (<xref linkend="ext.ffi.uffi.and.cffi"/>).</para>
+
+ <para>The most important component of the object is the memory region where
+ data is stored. By default &ECL; assumes that the user will perform automatic
+ managment of this memory, deleting the object when it is no longer
+ needed. The first reason is that this block may have been allocated by a
+ foreign routine using <function>malloc()</function>, or
+ <function>mmap()</function>, or statically, by referring to a C constant. The
+ second reason is that foreign functions may store references to this memory
+ which &ECL; is not aware of and, in order to keep these references valid,
+ &ECL; should not attempt to automatically destroy the object.</para>
+
+ <para>In many cases, however, it is desirable to automatically destroy
+ foreign objects once they have been used. The higher level interfaces &UFFI;
+ and &CFFI; provide tools for doing this. For instance, in the following
+ example adapted from the &UFFI; documentation, the string
+ <varname>NAME</varname> is automatically deallocated</para>
+<programlisting>(def-function "gethostname"
+ ((name (* :unsigned-char))
+ (len :int))
+ :returning :int)
+
+(if (zerop (c-gethostname (uffi:char-array-to-pointer name) 256))
+ (format t "Hostname: ~S" (ffi:convert-from-foreign-string name))
+ (error "gethostname() failed."))
+</programlisting>
+ </section>
+
+ <section xml:id="ext.ffi.uffi.and.cffi">
+ <title>Higher level interfaces</title>
+
+ <para>Up to now we have only discussed vague ideas about how a &FFI; works,
+ but you are probably more interested on how to actually code all these things
+ in lisp. You have here three possibilities:</para>
+ <itemizedlist>
+ <listitem>
+ <para>&ECL; supplies a high level interface which is compatible with
+ &UFFI;. Code designed for this library should run mostly unchanged with
+ &ECL;.</para>
+ </listitem>
+ <listitem>
+ <para>The &CFFI; library features a mostly complete backend for &ECL;. This
+ is however a work in progress, as the fact that &CFFI; allows for calling
+ arbitrary functions without declaring them causes some troubles with
+ &ECL;.</para>
+ </listitem>
+ <listitem>
+ <para>&ECL;'s own low level interface. Only to be used if &ECL; is your
+ deployment platform. It features some powerful constructs that allow you to
+ merge arbitrary C code with lisp (<xref linkend="ref.c-inline"/> and <xref
+ linkend="ref.clines"/>).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>In the following two subsections we will discuss two practical examples
+ of using the native &UFFI; and the &CFFI; library.</para>
+
+ <section xml:id="ext.ffi.uffi-example">
+ <title>UFFI example</title>
+
+ <para>The example below shows how to use &UFFI; in an application. There are
+ several important ingredients:
+ <itemizedlist>
+ <listitem><para>You need to specify the libraries you use and do it at the
+ toplevel, so that the compiler may include them at link
+ time.</para></listitem>
+ <listitem><para>Every function you will use has to be declared using
+ <function>uffi:def-function</function>.</para></listitem>
+ </itemizedlist>
+ </para>
+<programlisting>
+#|
+Build and load this module with (compile-file "uffi.lsp" :load t)
+|#
+;;
+;; This toplevel statement notifies the compiler that we will
+;; need this shared library at runtime. We do not need this
+;; statement in windows.
+;;
+#-(or ming32 windows)
+(uffi:load-foreign-library #+darwin "/usr/lib/libm.dylib"
+ #-darwin "/usr/lib/libm.so")
+;;
+;; With this other statement, we import the C function sin(),
+;; which operates on IEEE doubles.
+;;
+(uffi:def-function ("sin" c-sin) ((arg :double))
+ :returning :double)
+;;
+;; We now use this function and compare with the lisp version.
+;;
+(format t "~%Lisp sin:~t~d~%C sin:~t~d~%Difference:~t~d"
+ (sin 1.0d0) (c-sin 1.0d0) (- (sin 1.0d0) (c-sin 1.0d0)))
+</programlisting>
+ </section>
+
+ <section xml:id="ext.ffi.cffi-example">
+ <title>CFFI example</title>
+
+ <para>The &CFFI; library is an independent project and it is not shipped
+ with &ECL;. If you wish to use it you can go to their <ulink
+ url="http://www.common-lisp.net/cffi/">homepage</ulink>, download the code
+ and build it using &ASDF;.</para>
+
+ <para>&CFFI; differs slightly from &UFFI; in that functions may be used even
+ without being declared beforehand. This poses a few problems to the &ECL;
+ backend, but hopefully these should have been solved in the latest
+ releases.</para>
+<programlisting>
+#|
+Build and load this module with (compile-file "cffi.lsp" :load t)
+|#
+;;
+;; This toplevel statement notifies the compiler that we will
+;; need this shared library at runtime. We do not need this
+;; statement in windows.
+;;
+#-(or ming32 windows)
+(cffi:load-foreign-library #+darwin "/usr/lib/libm.dylib"
+ #-darwin "/usr/lib/libm.so")
+;;
+;; With this other statement, we import the C function sin(),
+;; which operates on IEEE doubles.
+;;
+(cffi:defcfun ("sin" c-sin) :double '(:double))
+;;
+;; We now use this function and compare with the lisp version.
+;;
+(format t "~%Lisp sin:~t~d~%C sin:~t~d~%Difference:~t~d"
+ (sin 1.0d0) (c-sin 1.0d0) (- (sin 1.0d0) (c-sin 1.0d0)))
+;;
+;; The following also works: no declaration!
+;;
+(let ((c-cos (cffi:foreign-funcall "cos" :double 1.0d0 :double)))
+ (format t "~%Lisp cos:~t~d~%C cos:~t~d~%Difference:~t~d"
+ (sin 1.0d0) c-sin (- (sin 1.0d0) c-sin)))
+</programlisting>
+ </section>
+
+ <section xml:id="ext.ffi.ecl-example">
+ <title>Low level example</title>
+
+ <para>To compare with the previous pieces of code, we show how the previous
+ programs would be written using <xref linkend="ref.clines"/> and <xref
+ linkend="ref.c-inline"/></para>
+<programlisting>
+#|
+Build and load this module with (compile-file "ecl.lsp" :load t)
+|#
+;;
+;; With this other statement, we import the C function sin(), which
+;; operates on IEEE doubles. Notice that we include the C header to
+;; get the full declaration.
+;;
+(defun c-sin (x)
+ (ffi:clines "#include <math.h>")
+ (ffi:c-inline (x) (:double) :double "sin(#0)" :one-liner t))
+;;
+;; We now use this function and compare with the lisp version.
+;;
+(format t "~%Lisp sin:~t~d~%C sin:~t~d~%Difference:~t~d"
+ (sin 1.0d0) (c-sin 1.0d0) (- (sin 1.0d0) (c-sin 1.0d0)))
+</programlisting>
+ </section>
+ </section>
+
+ <section xml:id="ext.ffi.dict">
+ <title>FFI Reference</title>
+ <toc/>
+
+<!-- ====================================================================== -->
+<!-- FFI:CLINES -->
+<!-- ====================================================================== -->
+
+ <refentry xml:id="ref.clines">
+ <refnamediv>
+ <refname><function>ffi:clines</function></refname>
+ <refpurpose>Insert C declarations and definitions</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Special form</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ffi:cline</funcdef>
+ <paramdef><parameter>c-code</parameter>*</paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <simplelist columns="2" type="horiz">
+ <member><replaceable>c-code</replaceable></member>
+ <member>One or more strings with C definitions. Not evaluated</member>
+
+ <member>returns</member>
+ <member>No value.</member>
+ </simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This special form inserts C code directly in the file that results
+ from compiling lisp sources. Contrary to <xref linkend="ref.c-inline"/>,
+ this function may have no executable statements, accepts no input value and
+ returnsn no value.</para>
+
+ <para>The main use of <function>FFI:CLINES</function> is to declare or
+ define C variables and functions that are going to be used later in other
+ &FFI; statements.</para>
+
+ <para><function>FFI:CLINES</function> is a special form that can only be
+ used in lisp compiled files as a toplevel form. Other uses will lead to an
+ error being signaled, either at compilation time or when loading the
+ file.</para>
+
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+
+ <para>In this example the <function>FFI:CLINES</function> statement is
+ required to get access to the C function <function>cos()</function></para>
+<programlisting>(ffi:clines "#include <math.h>")
+(defun cos (x)
+ (ffi:c-inline (x) (:double) :double "cos(#0)" :on-liner t))</programlisting>
+
+ </refsect1>
+ </refentry>
+
+<!-- ====================================================================== -->
+<!-- FFI:C-INLINE -->
+<!-- ====================================================================== -->
+
+ <refentry xml:id="ref.c-inline">
+ <refnamediv>
+ <refname><function>ffi:c-inline</function></refname>
+ <refpurpose>Inline C code in a lisp form.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Special form</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ffi:c-inline</funcdef>
+ <paramdef>(<parameter>lisp-value</parameter>*)</paramdef>
+ <paramdef>(<parameter>c-type</parameter>*)</paramdef>
+ <paramdef><parameter>return-type</parameter></paramdef>
+ <paramdef><parameter>C-code</parameter></paramdef>
+ <paramdef>&key;</paramdef>
+ <paramdef><parameter>one-liner</parameter></paramdef>
+ <paramdef><parameter>side-effects</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <simplelist columns="2" type="horiz">
+ <member><replaceable>lisp-value</replaceable></member>
+ <member>A lisp expression, evaluated.</member>
+
+ <member><replaceable>c-type</replaceable></member>
+ <member>A valid <acronym>FFI</acronym> type.</member>
+
+ <member><replaceable>return-type</replaceable></member>
+ <member>A valid <acronym>FFI</acronym> type or <code>(VALUES)</code>.</member>
+
+ <member><replaceable>C-code</replaceable></member>
+ <member>A string with valid C code plus some valid escape forms.</member>
+
+ <member><replaceable>one-liner</replaceable></member>
+ <member>A boolean, defaults to <symbol>NIL</symbol>.</member>
+
+ <member><replaceable>side-effects</replaceable></member>
+ <member>A boolean, defaults to <symbol>T</symbol>.</member>
+
+ <member>returns</member>
+ <member>One or more lisp values.</member>
+ </simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This is an special form which can be only used in compiled code and
+ whose purpose is to execute some C code getting and returning values from
+ and to the lisp environment.</para>
+
+ <para>The first argument to <function>ffi:c-inline</function> is a list of
+ lisp forms. These forms are going to be evaluated and their lisp values
+ will be transformed to the corresponding C types denoted by
+ <replaceable>c-type</replaceable>.</para>
+
+ <para>The input values are used to create a valid C expression using the
+ template in <replaceable>C-code</replaceable>. This is a string of
+ arbitrary size which mixes C expressions with two kind of
+ escape forms.</para>
+
+ <para>The first kind of escape form are made of a hash and a letter or a
+ number, as in: <code>#0</code>, <code>#1</code>, ..., until
+ <code>#z</code>. These codes are replaced by the corresponding input
+ values. The second kind of escape form has the format <code>@(return
+ <optional>n</optional>)</code>, it can be used as lvalue in a C expression
+ and it is used to set the n-th output value of the
+ <function>ffi:c-inline</function> form.</para>
+
+ <para>When the parameter <replaceable>one-liner</replaceable> is true, then
+ the C template must be a simple C statement that outputs a value. In this
+ case the use of <code>@(return)</code> is not allowed. When the parameter
+ <replaceable>one-liner</replaceable> is false, then the C template may be a
+ more complicated block form, with braces, conditionals, loops and spanning
+ multiple lines. In this case the output of the form can only be set using
+ <code>@(return)</code>.</para>
+
+ <para>Note that the conversion between lisp arguments and
+ <acronym>FFI</acronym> types is automatic. Note also that
+ <function>et:c-inline</function> cannot be used in interpreted or
+ bytecompiled code!</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>The following example implements the transcendental function
+ <function>SIN</function> using the C equivalent</para>
+ <programlisting>(ffi:c-lines "#include <math.h>")
+(defun mysin (x)
+ (ffi:c-inline (x) (:double) :double "sin(#0)" :one-liner t :side-effects nil))</programlisting>
+
+ <para>This function can also be implemented using the
+ <code>@(return)</code> form as follows:</para>
+ <programlisting>(defun mysin (x)
+ (ffi:c-inline (x) (:double) :double "@(return)=sin(#0);" :side-effects nil))</programlisting>
+
+ <para>The following example is slightly more complicated as it involves
+ loops and two output values:</para>
+ <programlisting>(defun sample (x)
+ (ffi:c-inline (n1 n2) (:int :int) (values :int :int) "{
+ int n1 = #0, n2 = #1, out1 = 0, out2 = 1;
+ while (n1 <= n2) {
+ out1 += n1;
+ out2 *= n1;
+ n1++;
+ }
+ @(return 0)= out1;
+ @(return 1)= out2;
+ }"
+ :side-effects nil))</programlisting>
+ </refsect1>
+ </refentry>
+ </section>
+</chapter>
+</book>
+ <!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+ -->
\ No newline at end of file
--- /dev/null
+#FIG 3.2 Produced by xfig version 3.2.5-alpha5
+Portrait
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+0 32 #f7fbff
+0 33 #ffefd7
+0 34 #efdfcf
+0 35 #8e8679
+0 36 #000000
+0 37 #8e8279
+0 38 #efe3e7
+0 39 #fff3f7
+0 40 #cfc3c7
+0 41 #8e8286
+0 42 #fffbcf
+0 43 #efebbe
+0 44 #cfcba6
+0 45 #8e8a71
+0 46 #dfffff
+0 47 #cfefef
+0 48 #b6cfcf
+0 49 #798a8e
+6 1575 3465 3645 4275
+1 1 0 3 0 39 50 0 40 0.000 1 0.0000 2610 3870 990 360 2610 3870 1620 3510
+4 0 0 50 0 19 32 0.0000 4 405 1110 2070 4050 KCL\001
+-6
+6 3420 5175 5490 5985
+1 1 0 3 0 39 50 0 40 0.000 1 0.0000 4469 5582 990 360 4469 5582 3479 5222
+4 0 0 50 0 19 32 0.0000 4 405 1080 3960 5760 ECL\001
+-6
+6 135 5220 2205 5985
+1 1 0 3 0 39 50 0 40 0.000 1 0.0000 1188 5602 990 360 1188 5602 198 5242
+4 0 0 50 0 19 32 0.0000 4 405 1500 540 5760 AKCL\001
+-6
+6 135 7110 2205 7875
+1 1 0 3 0 39 50 0 40 0.000 1 0.0000 1188 7492 990 360 1188 7492 198 7132
+4 0 0 50 0 19 32 0.0000 4 405 1140 630 7650 GCL\001
+-6
+6 3465 6345 5535 7155
+1 1 1 3 0 30 50 0 20 8.000 1 0.0000 4481 6766 990 360 4481 6766 5471 6766
+4 0 0 50 0 19 32 0.0000 4 405 1380 3832 6923 ECLs\001
+-6
+6 3510 7560 5580 8370
+1 1 0 3 0 30 50 0 20 0.000 1 0.0000 4533 7959 990 360 4533 7959 5523 7959
+4 0 0 50 0 19 32 0.0000 4 405 1080 4005 8130 ECL\001
+-6
+6 6930 6435 9360 7335
+1 1 0 3 0 39 50 0 40 0.000 1 0.0000 8141 6884 1157 420 8141 6884 6984 6464
+4 0 0 50 0 19 32 0.0000 4 405 1470 7425 7065 SBCL\001
+-6
+6 6030 3420 8730 4455
+1 1 0 3 0 39 50 0 40 0.000 1 0.0000 7386 3936 1299 473 7386 3936 6087 3464
+4 0 0 50 0 19 32 0.0000 4 405 1950 6390 4140 CMUCL\001
+-6
+6 3240 1170 6165 2610
+2 4 0 3 0 7 51 -1 20 0.000 0 0 7 0 0 5
+ 6120 2565 3285 2565 3285 1215 6120 1215 6120 2565
+4 0 0 50 0 19 32 0.0000 4 405 2340 3510 1755 Common\001
+4 0 0 50 -1 19 32 0.0000 4 510 1110 4050 2340 Lisp\001
+-6
+2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 2610 4230 1170 5220
+2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 2160 5580 3510 5580
+2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 1170 5940 1170 7110
+2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 4500 5940 4500 6390
+2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 2617 4252 4507 5220
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
+ 4680 2565 2655 3510 2700 3465
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+ 4635 2565 7380 3465
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+ 7515 4455 8100 6435
+2 1 1 3 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+ 1 1 3.00 180.00 360.00
+ 7065 4455 5220 7740
+2 1 1 3 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+ 1 1 3.00 180.00 360.00
+ 7110 7065 5265 7740
+2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 4500 7132 4500 7612
+4 0 0 50 0 19 32 0.0000 4 405 330 2662 5460 ?\001
+4 0 0 50 0 19 32 0.0000 4 405 330 3772 4717 ?\001
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en"><part xml:id="part.internals"><title>Internals</title>
+<partintro>
+ <para>&ECL; is an implementation of the Common-Lisp language that is based on a kernel
+ written in C plus a set of libraries written in Common-Lisp. The kernel includes a
+ bytecodes compiler, an interpreter, and enough functions to create and
+ manipulate all lisp objects. The lisp libraries provide higher level constructs
+ such as macro definitions, LOOPs, an implementation of CLOS, and a translator
+ from Lisp to C.</para>
+ <para>As a result of this design, which dates back to the Kyoto CL and was later
+ improved in Giuseppe Attardi's ECoLisp, &ECL; can be used as</para>
+ <itemizedlist mark="bullet">
+ <listitem>
+ <para>As a standalone implementation of the Common-Lisp language</para>
+ </listitem>
+ <listitem>
+ <para>As an embedded interpreter subject to the control of a larger C program.</para>
+ </listitem>
+ <listitem>
+ <para>As a Common-Lisp environment with C/C++ extensions.</para>
+ </listitem>
+ </itemizedlist>
+ <para role="continues">This manual describes the facility of &ECL; to interface the C language and
+ &ECL;. With this facility, the user can arrange his or her C-language
+ programs so that they can be invoked from &ECL;. In addition, the user can
+ write Lisp function definitions in the C language to increase runtime
+ efficiency.</para>
+</partintro>
+
+<chapter xml:id="Building-programs">
+ <title>Building programs</title>
+ <para>In this section we describe how you can use &ECL; to build programs and
+ loadable extensions that you can later on distribute to other people.</para>
+
+ <section xml:id="Internals-What-can-ECL-do-">
+ <title>What can &ECL; do?</title>
+ <para>Some day for some reasons you will be in the need to distribute code that
+ has been developed using &ECL;. In the following sections we will describe
+ the means that &ECL; offers you to do so. Basically, these are the
+ alternatives</para>
+ <variablelist>
+ <varlistentry>
+ <term>Source code</term>
+ <listitem>
+ <para>You distribute your programs in source code form. This is the easiest and most
+ portable way, but not the fastest one.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Standalone programs</term>
+ <listitem>
+ <para>You translate all your lisp code to C using the &ECL; compiler. The final
+ object files can be linked against other C/C++ libraries to obtain a standalone
+ executable.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>You can build statically and dynamically linked libraries.</term>
+ <listitem>
+ <para>You translate all your lisp code to C and combine the resulting object files
+ into a single library with <filename>.a</filename> extension. You can distribute this library
+ to other people and the final users can utilize these libraries to build
+ standalone programs.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>You can build dynamically loadable files.</term>
+ <listitem>
+ <para>This is the most flexible way. You translate all lisp code to C and link it
+ against possibly other C/C++ libraries to obtain a dynamically loadable library
+ (file type <filename>.so</filename> under unix). This library can be loaded a startup time to
+ add new functionality to the &ECL; environment.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>In several of these options, we have mentioned the possibility to include C/C++
+ code. Even if this is possible, you cannot use ordinary C/C++ compilers and
+ makefiles to build &ECL; extensions, let it be programs or
+ libraries. Briefly, you have to organize your code as follows</para>
+ <orderedlist numeration="arabic">
+ <listitem>
+ <para>Organize the C code as a library, let it be static or dynamic.</para>
+ </listitem>
+ <listitem>
+ <para>Build a function, say <literal>mymain()</literal>, in which the initialization phase
+ for your library is performed.</para>
+ </listitem>
+ <listitem>
+ <para>Group the code that interfaces to Lisp in separate C files, all of which
+ should include <literal>#include <ecl/ecl.h></literal> at the beginning.</para>
+ </listitem>
+ <listitem>
+ <para>Compile your lisp source files.</para>
+ </listitem>
+ <listitem>
+ <para>Let &ECL; build the final executable or library.</para>
+ </listitem>
+ </orderedlist>
+ <para role="continues">In the final step there are ways to instruct &ECL; to call your
+ initialization function (<literal>mymain()</literal> in the example above). These means
+ are explained in the following sections.</para>
+ <!-- -->
+ </section>
+
+ <section xml:id="Internals-Compiling-files">
+ <title>Compiling files</title>
+ <para>&ECL; supports two types of compilation. One is bytecodes compilation. This
+ process is performed on-the-fly, as you load source files with lisp code. This
+ leads to a series of bytes for each instruction, the so called
+ "bytecodes". These bytecodes are interpreted in a virtual machine, which is
+ written in C and which is reasonably fast.</para>
+ <para>The other type of compilation is the so-called "native" compilation. This
+ process consists on translating the lisp source file to C language. The
+ intermediate file is later compiled using a C compiler. The result is an object
+ file which may have different purposes.</para>
+ <variablelist>
+ <varlistentry>
+ <term>Dynamically loadable files or FASL (FASt Loadable) files</term>
+ <listitem>
+ <para>These are produced in a &ECL; built with support for dynamically loadable
+ libraries (Feature <replaceable>:DLOPEN</replaceable> is in <replaceable>*features*</replaceable>), when no extra
+ arguments are passed to <literal>compile-file</literal>. These object files typically have
+ the <filename>.fas</filename> extension, and can be loaded with <literal>load</literal>. They cannot be used
+ to build libraries nor standalone executable programs.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>linkable object files</term>
+ <listitem>
+ <para>These are produced when invoking <literal>compile-file</literal> with the keyword argument
+ <replaceable>:system-p</replaceable> set to true. The object file typically has the <filename>.o</filename>
+ extension. It cannot be loaded with <literal>load</literal>, but it can be used to build
+ libraries, standalone executable programs, or larger FASL files.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <!-- -->
+ </section>
+
+ <section xml:id="Internals-Building-standalone-executables">
+ <title>Building standalone executables</title>
+ <para>To build an executable you need a working &ECL; image with the
+ compiler. The function to build customized images is
+ <replaceable>c::build-program</replaceable>. The description of this function is as
+ follows. Care should be taken that <replaceable>image-name</replaceable> differs from any
+ filename in <replaceable>lisp-files</replaceable>.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>c:build-program</primary></indexterm> Function: <function>c:build-program</function> <varname>{</varname><varname>image-name</varname> <varname>&key</varname> <varname>lisp-files</varname> <varname>ld-flags</varname> <varname>prologue-code</varname> <varname>epilogue-code</varname><varname>}</varname></screen>
+ <para>This function builds a lisp image up from the core lisp library, plus all
+ components listed in <replaceable>lisp-files</replaceable>. Each component is either:</para>
+ <itemizedlist mark="bullet">
+ <listitem>
+ <para>A symbol: Names a statically linked library built from lisp code.</para>
+ </listitem>
+ <listitem>
+ <para>A string: Denotes an object file built from lisp code.</para>
+ </listitem>
+ </itemizedlist>
+ <para role="continues"><replaceable>ld-flags</replaceable> is a list of strings with additional parameters to be passed
+ to the linker. You can include here your favorite C/C++ libraries.</para>
+ <para><replaceable>prologue-code</replaceable> and <replaceable>epilogue-code</replaceable> are used to customize the
+ initialization process of the lisp image. In order to build the executable,
+ <replaceable>c:build-program</replaceable> first writes down a piece of C code which initializes the
+ lisp environment. You can customize the initialization process by suppling code
+ to be executed before (<replaceable>prologue-code</replaceable>) or after (<replaceable>epilogue-code</replaceable>)
+ setting up the lisp environment. Typically <replaceable>prologue-code</replaceable> defaults to an
+ empty string, while <replaceable>epilogue-code</replaceable> invokes the classical lisp
+ <replaceable>top-level</replaceable>. Additionally, as a convenience, <replaceable>epilogue-code</replaceable> can
+ be either a string with C code or also a list with a lisp form, which
+ will be interpreted at run time.</para>
+ </blockquote>
+ <!-- -->
+ </section>
+
+ <section xml:id="Internals-Building-libraries">
+ <title>Building libraries</title>
+ <para>To build a library you proceed more or less the same way as with standalone
+ executables. There are two different functions depending on whether you need
+ to build static or shared libraries.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>c:build-static-library</primary></indexterm> Function: <function>c:build-static-library</function> <varname>{</varname><varname>library-name</varname> <varname>&key</varname> <varname>lisp-files</varname> <varname>prologue-code</varname> <varname>epilogue-code</varname> <varname>init-name</varname><varname>}</varname></screen>
+ <screen><indexterm role="fn"><primary>c:build-shared-library</primary></indexterm> Function: <function>c:build-shared-library</function> <varname>{</varname><varname>library-name</varname> <varname>&key</varname> <varname>lisp-files</varname> <varname>prologue-code</varname> <varname>epilogue-code</varname> <varname>ld-flags</varname> <varname>init-name</varname><varname>}</varname></screen>
+ <para>This function builds a library file up from the object files listed in
+ <replaceable>lisp-files</replaceable>. Each of the arguments to <replaceable>lisp-file</replaceable> must name a single
+ object file produced with <literal>compile-file</literal>.</para>
+ <para><replaceable>library-name</replaceable> is the physical pathname corresponding to the library. The
+ value of <replaceable>library-name</replaceable> must follow some system-specific conventions. To
+ make your program portable, <replaceable>library-name</replaceable> should be built using the
+ output of <literal>compile-file-pathname</literal>.</para>
+ <para><replaceable>prologue-code</replaceable> and <replaceable>epilogue-code</replaceable> are strings with C code to be
+ executed before and after initializing the library, respectively. For
+ dynamically linked libraries you can also provide a list of strings in
+ <replaceable>ld-flags</replaceable>. These strings are additional parameters for the linker and
+ their purpose is to link C/C++ extensions into the library.</para>
+ <para><replaceable>init-name</replaceable> gives the initialization function of the library a
+ user-specified name. Thus a the generated library may be used and/or
+ linked to a C application.
+ The recommended way to invoke <replaceable>init-name</replaceable> is following:
+ <programlisting>
+ cl_object the_block = read_VV(OBJNULL, init_FOO /* function name specified by init-name */);
+ </programlisting>
+ Be sure to call <literal>cl_boot</literal> before the invocation of <replaceable>init-name</replaceable>.
+ In order to avoid that the returned object is garbage collected,
+ you should keep the result of <literal>read_VV</literal> in a local variable.
+ </para>
+ </blockquote>
+ <!-- -->
+ </section>
+
+ <section xml:id="Internals-File-names">
+ <title>File names</title>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>compile-file-pathname</primary></indexterm> Function: <function>compile-file-pathname</function> <varname>{</varname><varname>filename-base</varname> <varname>&key</varname> <varname>output-file</varname> <varname>type</varname><varname>}</varname></screen>
+ <para>When compiling lisp files, creating libraries, etc, a number of files are
+ produced which are of interest for the user or programmer. However, the name
+ of these files will change from system to system. The purpose of the function
+ <literal>compile-file-pathname</literal> is to query the compiler about the name of the
+ different files that it can produce. Possible values of the <replaceable>type</replaceable>
+ argument include:</para>
+ <variablelist>
+ <varlistentry>
+ <term>:fas (default)</term>
+ <listitem>
+ <para>Standard compiled files that can be loaded with <literal>load</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>:c, :data, :h</term>
+ <listitem>
+ <para>Intermediate files produced by the Lisp-to-C translator.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>:o</term>
+ <listitem>
+ <para>Linkable object files.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>:lib, :static-library</term>
+ <listitem>
+ <para>A normal library produced with <literal>c:build-static-library</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>:dll, :shared-library</term>
+ <listitem>
+ <para>A dynamically linked library produced with <literal>c:build-shared-library</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>:program</term>
+ <listitem>
+ <para>An executable produced with <literal>c:build-program</literal>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>The output of this function is system specific. For example, under FreeBSD<screen>
+ > (compile-file-pathname "/this/path/mylib" :type :lib)
+ #P"/this/path/libmylib.a"
+ > (compile-file-pathname "/this/path/mylib" :type :dll)
+ #P"/this/path/libmylib.so"
+ > (compile-file-pathname "/this/path/mycode")
+ #P"/this/path/mycode.fas"
+ </screen></para>
+ </blockquote>
+ <!-- -->
+ </section>
+
+ <section xml:id="Internals-Compiler-examples">
+ <title>Compiler examples</title>
+ <section>
+ <title>The <filename>hello.lisp</filename> file</title>
+ <para>In the following examples we will use the same lisp program. You have to
+ create a file called <filename>hello.lisp</filename> which contains the following lines</para>
+ <programlisting>
+ (princ "Hello world!")
+ (terpri)
+ (quit)
+ </programlisting>
+ <para role="continues">If you start &ECL; and load this file in the Common-Lisp environment you
+ will see the <literal>"Hello world!"</literal> message and the interpreter will be closed.<screen>
+ ECL (Embeddable Common-Lisp) 0.9d
+ Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
+ Copyright (C) 1993 Giuseppe Attardi
+ Copyright (C) 2000 Juan J. Garcia-Ripoll
+ ECL is free software, and you are welcome to redistribute it
+ under certain conditions; see file 'Copyright' for details.
+ Type :h for Help. Top level.
+ > <lineannotation>(load "hello.lisp")</lineannotation>
+ ;;; Loading "hello.lisp"
+ Hello World!
+ </screen></para>
+ </section>
+
+ <section>
+ <title>Example of loadable object file</title>
+ <para>You can only perform the example in this section if your &ECL; image supports
+ dynamically loading of object files. This is true if you find the keyword
+ <replaceable>:dlopen</replaceable> in the <replaceable>*features*</replaceable> variable. This is true, for instance,
+ in a typical FreeBSD or Linux box,<screen>
+ Type :h for Help. Top level.
+ > <lineannotation>*features*</lineannotation>
+ (:IEEE-FLOATING-POINT :IBM-PC :I386 :BSD :UNIX :DLOPEN :ANSI-CL :CLOS
+ :BOEHM-GC :ECL :COMMON)
+ </screen></para>
+ <para>In this example we build a loadable extension which prints the <literal>"Hello
+ world!"</literal> message. First you need to create a the <filename>hello.lisp</filename> file. Next
+ you have to enter the &ECL; environment and type <literal>(compile-file
+ "hello.lisp")</literal>. This produces a loadable object file.</para>
+ <para><screen>
+ Type :h for Help. Top level.
+ > <lineannotation>(compile-file "hello.lisp")</lineannotation>
+ ;;; Loading #P"/usr/lib/ecl/cmp.fas"
+ ;;; Loading #P"/usr/lib/ecl/sysfun.lsp"
+ ;;; Compiling hello.lisp.
+ ;;; End of Pass 1.
+ ;;; Calling the C compiler...
+ ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "hello.c" -o "hello.o"
+ ;;; Invoking external command: gcc -o "hello.fas" -L"/usr/lib/ecl/" "hello.o" -Wl,–rpath,/usr/lib/ecl/ -shared -lecl -lgmp -lgc -ldl -lm
+ ;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3
+ ;;; Finished compiling hello.lisp.
+ #P"hello.fas"
+ Top level.
+ > <lineannotation>(load "hello")</lineannotation>
+ ;;; Loading #P"hello.fas"
+ Hello World!
+ </screen></para>
+ </section>
+
+ <section>
+ <title>Example of standalone program</title>
+ <para>In this example we build a standalone program which prints the <literal>"Hello
+ world!"</literal> message and does nothing else. First you must create the
+ <filename>hello.lisp</filename> file shown above. Next you have to enter the &ECL;
+ environment and type <literal>(compile-file "hello.lisp" :system-p t)</literal>. This
+ produces an object file that can be linked against the &ECL; core image.</para>
+ <para><screen>
+ Type :h for Help. Top level.
+ > <lineannotation>(compile-file "hello.lisp" :system-p t)</lineannotation>
+ ;;; Loading #P"/usr/lib/ecl/cmp.fas"
+ ;;; Loading #P"/usr/lib/ecl/sysfun.lsp"
+ ;;; Compiling hello.lisp.
+ ;;; End of Pass 1.
+ ;;; Calling the C compiler...
+ ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "hello.c" -o "hello.o"
+ ;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3
+ ;;; Finished compiling hello.lisp.
+ #P"hello.o"
+ </screen></para>
+ <para role="continues">The final step is to build the executable using the <literal>c:build-program</literal>
+ instruction.<screen>
+ > <lineannotation>(c:build-program "myecl" :lisp-files '("hello.o"))</lineannotation>
+ ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "myecl.c" -o "myecl.o"
+ ;;; Invoking external command: gcc -o "myecl" -L"/usr/lib/ecl/" "myecl.o" "hello.o" -Wl,–rpath,/usr/lib/ecl/ -lecl -lgmp -lgc -ldl -lm
+ #P"myecl"
+ Top level.
+ </screen>Now you can execute this program from your favorite shell.</para>
+ <para role="continues"><screen>
+ % <lineannotation>./myecl</lineannotation>
+ Hello world!
+ </screen></para>
+ </section>
+
+ <section>
+ <title>Combining files into a larger FASL</title>
+ <para>You can only perform the example in this section if your &ECL; image supports
+ dynamically loading of object files. In this example we build a loadable
+ library which prints the <literal>"Hello world!"</literal> message and does nothing
+ else. First you must create the <filename>hello.lisp</filename> file shown above. Next you
+ have to enter the &ECL; environment and type <literal>(compile-file "hello.lisp"
+ :system-p t)</literal>. This produces an object file that can be linked to form a loadable
+ library.</para>
+ <para><screen>
+ Type :h for Help. Top level.
+ > (compile-file "hello.lisp" :system-p t)
+ ;;; Loading #P"/usr/lib/ecl/cmp.fas"
+ ;;; Loading #P"/usr/lib/ecl/sysfun.lsp"
+ ;;; Compiling hello.lisp.
+ ;;; End of Pass 1.
+ ;;; Calling the C compiler...
+ ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "hello.c" -o "hello.o"
+ ;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3
+ ;;; Finished compiling hello.lisp.
+ #P"hello.o"
+ </screen></para>
+ <para role="continues">The final step is to build the library using the <literal>c:build-fasl</literal>
+ instruction.<screen>
+ > (c:build-fasl "myecl" :lisp-files '("hello.o"))
+ ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl/" -w -c "myecl.c" -o "myecl.o"
+ ;;; Invoking external command: gcc -o "libmyecl.so" -L"/usr/lib/ecl/" "myecl.o" "hello.o" -Wl,–rpath,/usr/lib/ecl/ -shared -lecl -lgmp -lgc -ldl -lm
+ #P"libmyecl.so"
+ </screen>Now you can load this extension from any &ECL; image, even those you produce
+ with <literal>c:build-program</literal>.</para>
+ <para role="continues"><screen>
+ <<<<<<<< THIS EXAMPLE IS WRONG?! >>>>>>>>>
+ > (load "myecl")
+ ;;; Loading myecl.fas
+ Hello world!
+ Bye.
+ </screen></para>
+ <!-- -->
+ </section>
+ </section>
+</chapter>
+
+<chapter xml:id="Lisp-objects">
+ <title>Manipulating Lisp objects</title>
+ <para>If you want to extend, fix or simply customize &ECL; for your own needs,
+ you should understand how the implementation works.</para>
+
+ <section xml:id="Internals-Objects-representation">
+ <title>Objects representation</title>
+ <para>In &ECL; a lisp object is represented by a type called <literal>cl_object</literal>. This
+ type is a word which is long enough to host both an integer and a pointer. The
+ least significant bits of this word, also called the tag bits, determine
+ whether it is a pointer to a C structure representing a complex object, or
+ whether it is an immediate data, such as a fixnum or a character.</para>
+ <screen><![CDATA[
+ |-------------------|--|
+ | Fixnum value |01|
+ |-------------------|--|
+
+ |------------|------|--|
+ | Unused bits| char |10|
+ |------------|------|--|
+
+ |----------------------| |--------|--------|-----|--------|
+ | Pointer to cell |---->| word-1 | word-2 | ... | word-n |
+ |----------------------| |--------|--------|-----|--------|
+ | ...................00| | actual data of the object |
+ |----------------------| |--------------------------------|
+ ]]></screen>
+ <para>The fixnums and characters are called immediate datatypes, because they require
+ no more than the <literal>cl_object</literal> datatype to store all information. All other
+ &ECL; objects are non-immediate and they are represented by a pointer to a
+ cell that is allocated on the heap. Each cell consists of several words of
+ memory and contains all the information related to that object. By storing data
+ in multiples of a word size, we make sure that the least significant bits of a
+ pointer are zero, which distinguishes pointers from immediate data.</para>
+ <para>In an immediate datatype, the tag bits determine the type of the object. In
+ non-immediate datatypes, the first byte in the cell contains the secondary type
+ indicator, and distinguishes between different types of non immediate data. The
+ use of the remaining bytes differs for each type of object. For instance, a
+ cons cell consists of three words:</para>
+ <screen><![CDATA[
+ |---------|----------|
+ |CONS| | |
+ |---------|----------|
+ | car-pointer |
+ |--------------------|
+ | cdr-pointer |
+ |--------------------|
+ ]]></screen>
+ <para>There is one important function which tells the type of an object, plus several
+ macros which group several tests.</para>
+ <blockquote>
+ <screen><indexterm role="tp"><primary>cl_object</primary></indexterm> C type: <structname>cl_object</structname></screen>
+ <para>This is the type of a lisp object. For your C/C++ program, a <literal>cl_object</literal>
+ can be either a fixnum, a character, or a pointer to a union of structures (See
+ the header <filename>object.h</filename>). The actual interpretation of that object can be
+ guessed with the macro <literal>ecl_t_of</literal>.</para>
+ <para>For example, if <replaceable>x</replaceable> is of type <literal>cl_object</literal>, and it is of type fixnum,
+ we may retrieve its value</para>
+ <screen>
+ if (ecl_t_of(x) == t_fixnum)
+ printf("Integer value: %d\n", fix(x));
+ </screen>
+ <para role="continues">If <replaceable>x</replaceable> is of type <literal>cl_object</literal> and it does not contain an immediate
+ datatype, you may inspect the cell associated to the lisp object using <replaceable>x</replaceable>
+ as a pointer. For example,</para>
+ <screen>
+ if (ecl_t_of(x) == t_cons)
+ printf("CAR = %x, CDR = %x\n", x->cons.car, x->cons.cdr);
+ else if (ecl_t_of(x) == t_string)
+ printf("String: %s\n", x->string.self);
+ </screen>
+ <para role="continues">You should see the following sections and the header <filename>object.h</filename> to learn
+ how to use the different fields of a <literal>cl_object</literal> pointer.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="tp"><primary>cl_type</primary></indexterm> C type: <structname>cl_type</structname></screen>
+ <para>Enumeration type which distinguishes the different types of lisp objects. The
+ most important values are t_cons, t_fixnum, t_character, t_bignum, t_ratio,
+ t_singlefloat, t_doublefloat, t_complex, t_symbol, t_package, t_hashtable,
+ t_array, t_vector, t_string, t_bitvector, t_stream, t_random, t_readtable,
+ t_pathname, t_bytecodes, t_cfun, t_cclosure, t_gfun, t_instance, t_foreign and
+ t_thread.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>ecl_t_of</primary></indexterm> Function: <returnvalue>cl_type</returnvalue> <function>ecl_t_of</function> (<type>cl_object</type> <varname>O</varname>)</screen>
+ <para>If <replaceable>O</replaceable> is a valid lisp object, <literal>ecl_t_of(<replaceable>O</replaceable>)</literal> returns an integer
+ denoting the type that lisp object. That integer is one of the values of the
+ enumeration type <literal>cl_type</literal>.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>FIXNUMP</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>FIXNUMP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>CHARACTERP</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>CHARACTERP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>CONSP</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>CONSP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>LISTP</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>LISTP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>ATOM</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>ATOM</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>ARRAYP</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>ARRAYP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>VECTORP</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>VECTORP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>STRINGP</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>STRINGP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Different macros that check whether <replaceable>o</replaceable> belongs to the specified type.
+ These checks have been optimized, and are preferred over several calls to
+ <literal>ecl_t_of</literal>.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>IMMEDIATE</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>IMMEDIATE</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Tells whether <replaceable>o</replaceable> is an immediate datatype.</para>
+ </blockquote>
+ <!-- -->
+ </section>
+
+ <section xml:id="Internals-Constructing-objects">
+ <title>Constructing objects</title>
+ <para>On each of the following sections we will document the standard interface for
+ building objects of different types. For some objects, though, it is too
+ difficult to make a C interface that resembles all of the functionality in the
+ lisp environment. In those cases you need to</para>
+ <orderedlist numeration="arabic">
+ <listitem>
+ <para>build the objects from their textual representation, or</para>
+ </listitem>
+ <listitem>
+ <para>use the evaluator to build these objects.</para>
+ </listitem>
+ </orderedlist>
+ <para role="continues">The first way makes use of a C or Lisp string to construct an object. The two
+ functions you need to know are the following ones.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>c_string_to_object</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>c_string_to_object</function> (<type>const</type> <varname>char</varname> <type>*</type><varname>s</varname>)</screen>
+ <screen><indexterm role="fn"><primary>string_to_object</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>string_to_object</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para><literal>c_string_to_object</literal> builds a lisp object from a C string which contains a
+ suitable representation of a lisp object. <literal>string_to_object</literal> performs the
+ same task, but uses a lisp string, and therefore it is less useful. Two
+ examples of their use</para>
+ <screen>
+ /* Using a C string */
+ cl_object array1 = c_string_to_object("#(1 2 3 4)");
+
+ /* Using a Lisp string */
+ cl_object string = make_simple_string("#(1 2 3 4)");
+ cl_object array2 = string_to_object(string);
+ </screen>
+ </blockquote>
+ <!-- -->
+ </section>
+
+ <section xml:id="Internals-Integers">
+ <title>Integers</title>
+ <para>Common-Lisp distinguishes two types of integer types: bignums and fixnums. A
+ fixnum is a small integer, which ideally occupies only a word of memory and
+ which is between the values <replaceable>MOST-NEGATIVE-FIXNUM</replaceable> and
+ <replaceable>MOST-POSITIVE-FIXNUM</replaceable>. A bignum is any integer which is not a fixnum and
+ it is only constrained by the amount of memory available to represent it.</para>
+ <para>In &ECL; a fixnum is an integer that, together with the tag bits, fits in a
+ word of memory. The size of a word, and thus the size of a fixnum, varies from
+ one architecture to another, and you should refer to the types and constants in
+ the <filename>ecl.h</filename> header to make sure that your C extensions are portable.
+ All other integers are stored as bignums, they are not immediate objects, they
+ take up a variable amount of memory and the GNU Multiprecision Library is
+ required to create, manipulate and calculate with them.</para>
+ <blockquote>
+ <screen><indexterm role="tp"><primary>cl_fixnum</primary></indexterm> C type: <structname>cl_fixnum</structname></screen>
+ <para>This is a C signed integer type capable of holding a whole fixnum without any
+ loss of precision. The opposite is not true, and you may create a
+ <literal>cl_fixnum</literal> which exceeds the limits of a fixnum and should be stored as a
+ bignum.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="tp"><primary>cl_index</primary></indexterm> C type: <structname>cl_index</structname></screen>
+ <para>This is a C unsigned integer type capable of holding a nonnegative fixnum without
+ loss of precision. Typically, a <literal>cl_index</literal> is used as an index into an array,
+ or into a proper list, etc.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="vr"><primary>MOST_NEGATIVE_FIXNUM</primary></indexterm> Constant: <varname>MOST_NEGATIVE_FIXNUM</varname></screen>
+ <screen><indexterm role="vr"><primary>MOST_POSITIVE_FIXNUM</primary></indexterm> Constant: <varname>MOST_POSITIVE_FIXNUM</varname></screen>
+ <para>These constants mark the limits of a fixnum.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>FIXNUM_MINUSP</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>FIXNUM_MINUSP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>FIXNUM_PLUSP</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>FIXNUM_PLUSP</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>These functions perform the checks (<replaceable>o</replaceable> < 0) and (0 <= <replaceable>o</replaceable>),
+ respectively.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>MAKE_FIXNUM</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>MAKE_FIXNUM</function> (<type>cl_fixnum</type> <varname>n</varname>)</screen>
+ <screen><indexterm role="fn"><primary>fix</primary></indexterm> Function: <returnvalue>cl_fixnum</returnvalue> <function>fix</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para><literal>MAKE_FIXNUM</literal> and <literal>fix</literal> convert from an integer to a lisp object
+ of fixnum type and vice versa. These functions no not check their arguments.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>fixint</primary></indexterm> Function: <returnvalue>cl_fixnum</returnvalue> <function>fixint</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Converts a lisp fixnum to a C integer of the appropriate size. Signals an error
+ if <replaceable>o</replaceable> is not of fixnum type.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>fixnnint</primary></indexterm> Function: <returnvalue>cl_index</returnvalue> <function>fixnnint</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Similar to <literal>fixint</literal> but also ensures that <replaceable>o</replaceable> is not negative.</para>
+ </blockquote>
+ <!-- -->
+ </section>
+
+ <section xml:id="Internals-Characters">
+ <title>Characters</title>
+ <para>&ECL; has only one type of characters, which fits in the C type <literal>char</literal>.
+ The following constants and functions operate on characters.</para>
+ <blockquote>
+ <screen><indexterm role="vr"><primary>CHAR_CODE_LIMIT</primary></indexterm> Constant: <varname>CHAR_CODE_LIMIT</varname></screen>
+ <para>Each character is assigned an integer code which ranges from 0 to
+ (<replaceable>CHAR_CODE_LIMIT</replaceable>-1).</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>CHAR_CODE</primary></indexterm> Function: <returnvalue>cl_fixnum</returnvalue> <function>CHAR_CODE</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <screen><indexterm role="fn"><primary>char_code</primary></indexterm> Function: <returnvalue>cl_fixnum</returnvalue> <function>char_code</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Returns the integer code associated to a lisp character. Only <literal>char_code</literal>
+ checks its arguments.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>CODE_CHAR</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>CODE_CHAR</function> (<type>cl_fixnum</type> <varname>o</varname>)</screen>
+ <para>Returns the lisp character associated to an integer code. It does not check
+ its arguments.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>coerce_to_character</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>coerce_to_character</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Coerces a lisp object to type character. Valid arguments are a character,
+ or a string designator of length 1. In all other cases an error is signaled.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>char_eq</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>char_eq</function> (<type>cl_object</type> <varname>x</varname>, <type>cl_object</type> <varname>y</varname>)</screen>
+ <screen><indexterm role="fn"><primary>char_equal</primary></indexterm> Function: <returnvalue>bool</returnvalue> <function>char_equal</function> (<type>cl_object</type> <varname>x</varname>, <type>cl_object</type> <varname>y</varname>)</screen>
+ <para>Compare two characters for equality. <literal>char_eq</literal> take case into account and
+ <literal>char_equal</literal> ignores it.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>char_cmp</primary></indexterm> Function: <returnvalue>int</returnvalue> <function>char_cmp</function> (<type>cl_object</type> <varname>x</varname>, <type>cl_object</type> <varname>y</varname>)</screen>
+ <screen><indexterm role="fn"><primary>char_compare</primary></indexterm> Function: <returnvalue>int</returnvalue> <function>char_compare</function> (<type>cl_object</type> <varname>x</varname>, <type>cl_object</type> <varname>y</varname>)</screen>
+ <para>Compare the relative order of two characters. <literal>char_cmp</literal> takes care of
+ case and <literal>char_compare</literal> converts all characters to uppercase before
+ comparing them.</para>
+ </blockquote>
+ <!-- -->
+ </section>
+
+ <section xml:id="Internals-Arrays">
+ <title>Arrays</title>
+ <para>An array is an aggregate of data of a common type, which can be accessed with
+ one or more nonnegative indices. &ECL; stores arrays as a C structure with a
+ pointer to the region of memory which contains the actual data. The cell
+ of an array datatype varies depending on whether it is a vector, a bytevector,
+ a multidimensional array or a string.</para>
+ <para>If <replaceable>x</replaceable> contains a vector, you can access the following fields:</para>
+ <variablelist>
+ <varlistentry>
+ <term><literal>x->vector.elttype</literal></term>
+ <listitem>
+ <para>The type of the elements of the vector.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->vector.dim</literal></term>
+ <listitem>
+ <para>The maximum number of elements.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->vector.fillp</literal></term>
+ <listitem>
+ <para>Actual number of elements in the vector or "fill pointer".</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->vector.self</literal></term>
+ <listitem>
+ <para>Union of pointers of different types. You should choose the right pointer
+ depending on <literal>x->vector.elltype</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->vector.hasfillp</literal></term>
+ <listitem>
+ <para>Whether <literal>x->vector.fillp</literal> can be smaller than <literal>x->vector.dim</literal>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>If <replaceable>x</replaceable> contains a multidimensional array, the cell elements become</para>
+ <variablelist>
+ <varlistentry>
+ <term><literal>x->array.elttype</literal></term>
+ <listitem>
+ <para>The type of the elements of the array.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->array.dim</literal></term>
+ <listitem>
+ <para>Number of elements in the array.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->array.rank</literal></term>
+ <listitem>
+ <para>Number of dimensions of the array.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->array.dims[]</literal></term>
+ <listitem>
+ <para>Array with the dimensions of the array. The elements range from
+ <literal>x->array.dim[0]</literal> to <literal>x->array.dim[x->array.rank-1]</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->array.self</literal></term>
+ <listitem>
+ <para>Union of pointers to the actual data. You should choose the right pointer
+ depending on <literal>x->array.elltype</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->array.rank</literal></term>
+ <listitem>
+ <para>Whether <literal>x->vector.fillp</literal> can be smaller than <literal>x->vector.dim</literal>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para role="continues">Bitvectors and strings are treated separately.</para>
+ <para>Each array is of an specialized type which is the type of the elements of the
+ array. &ECL; has arrays only a few following specialized types, and for each
+ of these types there is a C integer which is the corresponding value of
+ <literal>x->array.elttype</literal> or <literal>x->vector.elttype</literal>. We list those types
+ together with the C constant that denotes that type:</para>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>T</replaceable></term>
+ <listitem>
+ <para><literal>aet_object</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>CHARACTER</replaceable></term>
+ <listitem>
+ <para><literal>aet_ch</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>FIXNUM</replaceable></term>
+ <listitem>
+ <para><literal>aet_fix</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>BIT</replaceable></term>
+ <listitem>
+ <para><literal>aet_bit</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>SINGLE-FLOAT</replaceable></term>
+ <listitem>
+ <para><literal>aet_sf</literal></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>DOUBLE-FLOAT</replaceable></term>
+ <listitem>
+ <para><literal>aet_df</literal></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>array_elttype</primary></indexterm> Function: <returnvalue>cl_elttype</returnvalue> <function>array_elttype</function> (<type>cl_object</type> <varname>o</varname>)</screen>
+ <para>Returns the element type of the array <replaceable>o</replaceable>, which can be a string, a
+ bitvector, vector, or a multidimensional array. For example, the code
+ <literal>array_elttype(c_string_to_object("\"AAA\""))</literal> returns <literal>aet_ch</literal>,
+ while the <literal>array_elttype(c_string_to_object("#(A B C)"))</literal> returns
+ <literal>aet_object</literal>.</para>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>aref</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>aref</function> (<type>cl_object</type> <varname>array</varname>, <type>cl_index</type> <varname>index</varname>)</screen>
+ <screen><indexterm role="fn"><primary>aset</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>aset</function> (<type>cl_object</type> <varname>array</varname>, <type>cl_index</type> <varname>index</varname>, <type>cl_object</type> <varname>value</varname>)</screen>
+ <para>These functions are used to retrieve and set the elements of an array. The
+ elements are accessed with one index, <replaceable>index</replaceable>, as in the lisp function
+ <literal>ROW-MAJOR-AREF</literal>. For example</para>
+ <screen>
+ cl_object array = c_string_to_object("#2A((1 2) (3 4))");
+ cl_object x = aref(array, 3);
+ cl_print(1, x); /* Outputs 4 */
+ aset(array, 3, MAKE_FIXNUM(5));
+ cl_print(1, array); /* Outputs #2A((1 2) (3 5)) */
+ </screen>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>aref1</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>aref1</function> (<type>cl_object</type> <varname>vector</varname>, <type>cl_index</type> <varname>index</varname>)</screen>
+ <screen><indexterm role="fn"><primary>aset1</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>aset1</function> (<type>cl_object</type> <varname>vector</varname>, <type>cl_index</type> <varname>index</varname>, <type>cl_object</type> <varname>value</varname>)</screen>
+ <para>These functions are similar to <literal>aref</literal> and <literal>aset</literal>, but they operate on
+ vectors.</para>
+ <screen>
+ cl_object array = c_string_to_object("#(1 2 3 4)");
+ cl_object x = aref1(array, 3);
+ cl_print(1, x); /* Outputs 4 */
+ aset1(array, 3, MAKE_FIXNUM(5));
+ cl_print(1, array); /* Outputs #(1 2 3 5) */
+ </screen>
+ </blockquote>
+ <!-- -->
+ </section>
+
+ <section xml:id="Internals-Strings">
+ <title>Strings</title>
+ <para>A string, both in Common-Lisp and in &ECL; is nothing but a vector of
+ characters. Therefore, almost everything mentioned in the section of arrays
+ remains valid here. The only important difference is that &ECL; stores
+ strings as a lisp object with a pointer to a zero terminated C string. Thus, if
+ a string has <replaceable>n</replaceable> characters, &ECL; will reserve <replaceable>n</replaceable>+1 bytes for the
+ string. This allows us to pass the string <literal>self</literal> pointer to any C
+ routine.</para>
+ <para>If <replaceable>x</replaceable> is a lisp object of type string, we can access the following fields:</para>
+ <variablelist>
+ <varlistentry>
+ <term><literal>x->string.dim</literal></term>
+ <listitem>
+ <para>Maximum number of characters that it can contain.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->string.fillp</literal></term>
+ <listitem>
+ <para>Actual number of characters in the string.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->string.self</literal></term>
+ <listitem>
+ <para>Pointer to the characters.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>x->string.hasfillp</literal></term>
+ <listitem>
+ <para>True if <literal>x->string.fillp</literal> can be smaller than <literal>x->string.dim</literal>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>make_simple_string</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>make_simple_string</function> (<type>char</type> <varname>*</varname><varname>s</varname>)</screen>
+ <screen><indexterm role="fn"><primary>make_string_copy</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>make_string_copy</function> (<type>char</type> <varname>*</varname><varname>s</varname>)</screen>
+ <para>Both routines build a lisp string from a C string. <literal>make_string_copy</literal>
+ allocates new space and copies the content of the string to
+ it. <literal>make_simple_string</literal> simply uses the memory pointed by <replaceable>s</replaceable>, which
+ should not be deallocated. Both routines use <literal>strlen</literal> to calculate the
+ length of the string.</para>
+ </blockquote>
+ </section>
+
+ <section xml:id="Internals-Bitvectors">
+ <title>Bitvectors</title>
+ </section>
+
+ <section xml:id="Internals-Streams">
+ <title>Streams</title>
+ </section>
+
+ <section xml:id="Internals-Structures">
+ <title>Structures</title>
+ </section>
+
+ <section xml:id="Internals-Instances">
+ <title>Instances</title>
+ <!-- -->
+ </section>
+
+ <section xml:id="Internals-Bytecodes">
+ <title>Bytecodes</title>
+ <para>A bytecodes object is a lisp object with a piece of code that can be
+ interpreted. The objects of type <literal>t_bytecode</literal> are implicitly constructed
+ by a call to <literal>eval</literal>, but can also be explicitly constructed with the
+ <literal>make_lambda</literal> function.</para>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>cl_safe_eval</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>cl_safe_eval</function> (<type>cl_object</type> <varname>form</varname>, <type>cl_object</type> <varname>env</varname>, <type>cl_object</type> <varname>err_value</varname></screen>
+ <screen><indexterm role="fn"><primary>cl_eval</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>cl_eval</function> (<type>cl_object</type> <varname>form</varname>)</screen>
+ <para><literal>cl_safe_eval</literal> evaluates <replaceable>form</replaceable> in the lexical environment <replaceable>env</replaceable>,
+ which can be <replaceable>nil</replaceable>. Before evaluating it, the expression <replaceable>form</replaceable> must
+ be bytecompiled. <literal>cl_eval</literal> is the equivalent of <literal>cl_safe_eval</literal> but
+ without environment and with <replaceable>err_value</replaceable> set to <replaceable>nil</replaceable>. It exists only
+ for compatibility with previous versions.</para>
+ <screen>
+ cl_object form = c_string_to_object("(print 1)");
+ cl_safe_eval(form,Cnil);
+ cl_safe_eval(form, Cnil);
+ </screen>
+ </blockquote>
+ <blockquote>
+ <screen><indexterm role="fn"><primary>si_make_lambda</primary></indexterm> Function: <returnvalue>cl_object</returnvalue> <function>si_make_lambda</function> (<type>cl_object</type> <varname>name</varname>, <type>cl_object</type> <varname>def</varname>)</screen>
+ <para>Builds an interpreted lisp function with name given by the symbol <replaceable>name</replaceable>
+ and body given by <replaceable>def</replaceable>. For instance, we would achieve the equivalent of</para>
+ <programlisting>
+ (funcall #'(lambda (x y) (block foo (+ x y)))
+ 1 2)
+ </programlisting>
+ <para role="continues">with the following code</para>
+ <screen>
+ cl_object def = c_string_to_object("((x y) (+ x y))");
+ cl_object name = _intern("foo")
+ cl_object fun = si_make_lambda(name, def);
+ return funcall(fun, MAKE_FIXNUM(1), MAKE_FIXNUM(2));
+ </screen>
+ <para role="continues">Notice that <literal>si_safe_lambda</literal> performs a bytecodes compilation
+ of the definition and thus it may signal some errors. Such errors are not
+ handled by the routine itself you might consider using <literal>cl_safe_eval</literal>
+ or <literal>cl_eval</literal> instead:</para>
+ <screen>
+ cl_object def = c_string_to_object("#'(lambda-block foo (x y) (+ x y))");
+ cl_object fun = cl_eval(def);
+ return funcall(fun, MAKE_FIXNUM(1), MAKE_FIXNUM(2));
+ </screen>
+ </blockquote>
+ <!-- -->
+ </section>
+</chapter>
+
+<chapter xml:id="Internals-the-interpreter">
+ <title>The interpreter</title>
+ <section xml:id="Internals-ECL-stacks">
+ <title>&ECL; stacks</title>
+ <para>&ECL; uses the following stacks:</para>
+ <variablelist>
+ <varlistentry>
+ <term>Frame Stack</term>
+ <listitem>
+ <para>consisting of catch, block, tagbody frames</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Bind Stack</term>
+ <listitem>
+ <para>for shallow binding of dynamic variables</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Interpreter Stack</term>
+ <listitem>
+ <para>acts as a Forth data stack, keeping intermediate arguments to
+ interpreted functions, plus a history of called functions.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>C Control Stack</term>
+ <listitem>
+ <para>used for arguments/values passing, typed lexical variables,
+ temporary values, and function invocation.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </section>
+
+ <section xml:id="Internals-Procedure-Call-Conventions">
+ <title>Procedure Call Conventions</title>
+ <para>&ECL; employs standard C calling conventions to achieve efficiency and
+ interoperability with other languages.
+ Each Lisp function is implemented as a C function which takes as many
+ argument as the Lisp original plus one additional integer argument
+ which holds the number of actual arguments. The function sets <literal>NValues</literal>
+ to the number of Lisp values produced, it returns the first one and the
+ remaining ones are kept in a global (per thread) array (<literal>VALUES</literal>).</para>
+ <para>To show the argument/value passing mechanism, here we list the actual
+ code for the Common-Lisp function <literal>cons</literal>.</para>
+ <screen>
+ cl_cons(int narg, object car, object cdr)
+ { object x;
+ check_arg(2);
+ x = alloc_object(t_cons);
+ CAR(x) = car;
+ CDR(x) = cdr;
+ NValues = 1;
+ return x;
+ }
+ </screen>
+ <para>&ECL; adopts the convention that the name of a function that implements a
+ Common-Lisp function begins with a short package name (<literal>cl</literal> for COMMON-LISP,
+ <literal>si</literal> for SYSTEM, etc), followed by <literal>L</literal>, and followed by the name of
+ the Common-Lisp function. (Strictly speaking, `<literal>-</literal>' and `<literal>*</literal>' in the
+ Common-Lisp function name are replaced by `<literal>_</literal>' and `<literal>A</literal>', respectively,
+ to obey the syntax of C.)</para>
+ <para><literal>check_arg(2)</literal> in the code of <literal>cl_cons</literal> checks that exactly two
+ arguments are supplied to <literal>cons</literal>. That is, it checks that <literal>narg</literal> is
+ 2, and otherwise, it causes an error. <literal>allocate_object(t_cons)</literal> allocates
+ a cons cell in the heap and returns the pointer to the cell. After the
+ <literal>CAR</literal> and the <literal>CDR</literal> fields of the cell are set, the cell pointer is
+ returned directly. The number assigned to NValues set by the function (1 in
+ this case) represents the number of values of the function.</para>
+ <para>In general, if one is to play with the C kernel of &ECL; there is no need to
+ know about all these conventions. There is a preprocessor that takes care of
+ the details, by using a lisp representation of the statements that output
+ values, and of the function definitions. For instance, the actual source code
+ for <literal>cl_cons</literal> in <filename>src/c/lists.d</filename></para>
+ <screen>
+ @(defun cons (car cdr)
+ @
+ @(return CONS(car, cdr))
+ @)
+ </screen>
+ </section>
+
+ <section xml:id="Internals-The-lexical-environment">
+ <title>The lexical environment</title>
+ <para>The &ECL; interpreter uses two A-lists (Association lists) to
+ represent lexical environments.</para>
+ <itemizedlist mark="bullet">
+ <listitem>
+ <para>One for variable bindings</para>
+ </listitem>
+ <listitem>
+ <para>One for local function/macro/tag/block bindings</para>
+ </listitem>
+ </itemizedlist>
+ <para>When a function closure is created, the current two A-lists are
+ saved in the closure along with the lambda expression. Later, when the
+ closure is invoked, the saved A-lists are
+ used to recover the lexical environment.</para>
+ </section>
+
+ <section xml:id="Internals-The-interpreter-stack">
+ <title>The interpreter stack</title>
+ <para>The bytecodes interpreter uses a stack of its own to save and restore values
+ from intermediate calculations. This Forth-like data stack is also used in
+ other parts of the C kernel for various purposes, such as saving compiled code,
+ keeping arguments to FORMAT, etc.</para>
+ <para>However, one of the most important roles of the Interpreter Stack is to keep a
+ log of the functions which are called during the execution of bytecodes. For
+ each function invoked, the interpreter keeps three lisp objects on the stack:</para>
+ <screen><![CDATA[
+ +----------+------------------------------------------------+
+ | function | lexical environment | index to previous record |
+ +----------+---------------------+--------------------------+
+ ]]></screen>
+ <para>The first item is the object which is funcalled. It can be a bytecodes object,
+ a compiled function or a generic function. In the last two cases the lexical
+ environment is just NIL. In the first case, the second item on the stack is
+ the lexical environment on which the code is executed. Each of these records
+ are popped out of the stack after function invocation.</para>
+ <para>Let us see how these invocation records are used for debugging.<screen>
+ >(defun fact (x) ;;; Wrong definition of the
+ (if (= x 0) ;;; factorial function.
+ one ;;; one should be 1.
+ (* x (fact (1- x)))))
+ FACT
+
+ >(fact 3) ;;; Tries 3!
+ Error: The variable ONE is unbound.
+ Error signalled by IF.
+ Broken at IF.
+ >>:b ;;; Backtrace.
+ Backtrace: eval > fact > if > fact > if > fact > if > fact > IF
+ ;;; Currently at the last IF.
+ >>:h ;;; Help.
+
+ Break commands:
+ :q(uit) Return to some previous break level.
+ :pop Pop to previous break level.
+ :c(ontinue) Continue execution.
+ :b(acktrace) Print backtrace.
+ :f(unction) Show current function.
+ :p(revious) Go to previous function.
+ :n(ext) Go to next function.
+ :g(o) Go to next function.
+ :fs Search forward for function.
+ :bs Search backward for function.
+ :v(ariables) Show local variables, functions, blocks, and tags.
+ :l(ocal) Return the nth local value on the stack.
+ :hide Hide function.
+ :unhide Unhide function.
+ :hp Hide package.
+ :unhp Unhide package.
+ :unhide-all Unhide all variables and packages.
+ :bds Show binding stack.
+ :m(essage) Show error message.
+ :hs Help stack.
+ Top level commands:
+ :cf Compile file.
+ :exit or ^D Exit Lisp.
+ :ld Load file.
+ :step Single step form.
+ :tr(ace) Trace function.
+ :untr(ace) Untrace function.
+
+ Help commands:
+ :apropos Apropos.
+ :doc(ument) Document.
+ :h(elp) or ? Help. Type ":help help" for more information.
+
+ >>:p ;;; Move to the last call of FACT.
+ Broken at IF.
+
+ >>:b
+ Backtrace: eval > fact > if > fact > if > fact > if > FACT > if
+ ;;; Now at the last FACT.
+ >>:v ;;; The environment at the last call
+ Local variables: ;;; to FACT is recovered.
+ X: 0 ;;; X is the only bound variable.
+ Block names: FACT. ;;; The block FACT is established.
+
+ >>x
+ 0 ;;; The value of x is 0.
+
+ >>(return-from fact 1) ;;; Return from the last call of
+ 6 ;;; FACT with the value of 0.
+ ;;; The execution is resumed and
+ > ;;; the value 6 is returned.
+ ;;; Again at the top-level loop.
+ </screen></para>
+ <!-- -->
+ </section>
+</chapter>
+
+<chapter xml:id="Internals-the-compiler">
+ <title>The compiler</title>
+ <section xml:id="Internals-The-compiler-translates-to-C">
+ <title>The compiler translates to C</title>
+ <para>The &ECL; compiler is essentially a translator from Common-Lisp to C. Given
+ a Lisp source file, the compiler first generates three intermediate
+ files:</para>
+ <itemizedlist mark="bullet">
+ <listitem>
+ <para>a C-file which consists of the C version of the Lisp program</para>
+ </listitem>
+ <listitem>
+ <para>an H-file which consists of declarations referenced in the C-file</para>
+ </listitem>
+ <listitem>
+ <para>a Data-file which consists of Lisp data to be used at load time</para>
+ </listitem>
+ </itemizedlist>
+ <para>The &ECL; compiler then invokes the C compiler to compile the
+ C-file into an object file. Finally, the contents of the Data-file is
+ appended to the object file to make a <emphasis>Fasl-file</emphasis>. The generated
+ Fasl-file can be loaded into the &ECL; system by the Common-Lisp
+ function <literal>load</literal>. By default, the three intermediate files are
+ deleted after the compilation, but, if asked, the compiler leaves
+ them.</para>
+ <para>The merits of the use of C as the intermediate language are:</para>
+ <itemizedlist mark="-">
+ <listitem>
+ <para>The &ECL; compiler is highly portable.</para>
+ </listitem>
+ <listitem>
+ <para>Cross compilation is possible, because the contents of the
+ intermediate files are common to all versions of &ECL;. For example,
+ one can compile his or her Lisp program by the &ECL; compiler on
+ a Sun, bring the intermediate files to DOS, compile the C-file with
+ the gcc compiler under DOS, and then append the Data-file to the object
+ file. This procedure generates the Fasl-file for the &ECL; system on
+ DOS. This kind of cross compilation makes it easier to port &ECL;.</para>
+ </listitem>
+ <listitem>
+ <para>Hardware-dependent optimizations such as register allocations
+ are done by the C compiler.</para>
+ </listitem>
+ </itemizedlist>
+ <para>The demerits are:</para>
+ <itemizedlist mark="-">
+ <listitem>
+ <para>At those sites where no C compiler is available,
+ the users cannot compile their Lisp programs.</para>
+ </listitem>
+ <listitem>
+ <para>The compilation time is long. 70% to 80% of the
+ compilation time is used by the C compiler. The &ECL; compiler is
+ therefore slower than compiler generating machine code directly.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ <section xml:id="Internals-The-compiler-mimics-human-C-programmer">
+ <title>The compiler mimics human C programmer</title>
+ <para>The format of the intermediate C code generated by the &ECL; compiler is the
+ same as the hand-coded C code of the &ECL; source programs. For example,
+ supposing that the Lisp source file contains the
+ following function definition:</para>
+ <programlisting>
+ (defvar *delta* 2)
+ (defun add1 (x) (+ *delta* x))
+ </programlisting>
+ <para role="continues">The compiler generates the following intermediate C code.</para>
+ <screen>
+ /* function definition for ADD1 */
+ static cl_object L1(cl_object V1)
+ { VT2 VLEX2 CLSR2
+ cl_object value0;
+ value0=number_plus(symbol_value(VV[0]),V1); NVALUES=1;
+ return value0;
+ }
+ /* initialization of this module */
+ void init_CODE(cl_object flag)
+ { VT1 CLSR1
+ cl_object value0;
+ if (!FIXNUMP(flag)){
+ Cblock=flag;
+ #ifndef ECL_DYNAMIC_VV
+ flag->cblock.data = VV;
+ #endif
+ flag->cblock.self_destruct=0;
+ flag->cblock.data_size = VM;
+ flag->cblock.data_text = compiler_data_text;
+ flag->cblock.data_text_size = compiler_data_text_size;
+ return;}
+ #ifdef ECL_DYNAMIC_VV
+ VV = Cblock->cblock.data;
+ #endif
+ T0= MAKE_FIXNUM(2);
+ si_Xmake_special(VV[0])
+ if(SYM_VAL(T0)!=OBJNULL) cl_setq(VV[0],T0);
+ cl_def_c_function(VV[1],(void*)L1,1);
+ }
+ </screen>
+ <para>The C function <literal>L1</literal> implements the Lisp function <literal>add1</literal>.
+ This relation is established by <literal>cl_def_c_function</literal> in the
+ initialization function <literal>init_CODE</literal>, which is invoked at load
+ time. There, the vector <literal>VV</literal> consists of Lisp objects;
+ <literal>VV[0]</literal> and <literal>VV[1]</literal> in this example hold the Lisp symbols
+ <literal>*delta*</literal> and <literal>add1</literal>. <literal>VM</literal> in the definition of
+ <literal>L1</literal> is a C macro declared in the corresponding H-file. The
+ actual value of <literal>VM</literal> is the number of value stack locations used
+ by this module, i.e., 2 in this example. Thus the following macro
+ definition is found in the H-file.</para>
+ <screen>
+ #define VM 2
+ </screen>
+ </section>
+
+ <section xml:id="Internals-Implementation-of-Compiled-Closures">
+ <title>Implementation of Compiled Closures</title>
+ <para>The &ECL; compiler takes two passes before it invokes the C
+ compiler. The major role of the first pass is to detect function
+ closures and to detect, for each function closure, those lexical
+ objects (i.e., lexical variable, local function definitions, tags, and
+ block-names) to be enclosed within the closure. This check must be
+ done before the C code generation in the second pass, because lexical
+ objects to be enclosed in function closures are treated in a different
+ way from those not enclosed.</para>
+ <para>Ordinarily, lexical variables in a compiled function <emphasis>f</emphasis>
+ are allocated on the C stack. However, if a lexical variable is
+ to be enclosed in function closures, it is allocated on a list, called
+ the "environment list", which is local to <emphasis>f</emphasis>. In addition, a
+ local variable is created which points to the lexical
+ variable's location (within the environment list), so that
+ the variable may be accessed through an indirection rather than by list
+ traversal.</para>
+ <para>The environment list is a pushdown list: It is empty when <emphasis>f</emphasis> is called.
+ An element is pushed on the environment list when a variable to be enclosed in
+ closures is bound, and is popped when the binding is no more in effect. That
+ is, at any moment during execution of <emphasis>f</emphasis>, the environment list contains
+ those lexical variables whose binding is still in effect and which should be
+ enclosed in closures. When a compiled closure is created during execution of
+ <emphasis>f</emphasis>, the compiled code for the closure is coupled with the environment
+ list at that moment to form the compiled closure.</para>
+ <para>Later, when the compiled closure is invoked, a pointer is set up to each
+ lexical variable in the environment list, so that each object may be referenced
+ through a memory indirection.</para>
+ <para>Let us see an example. Suppose the following function has been compiled.</para>
+ <programlisting>
+ (defun foo (x)
+ (let ((a #'(lambda () (incf x)))
+ (y x))
+ (values a #'(lambda () (incf x y)))))
+ </programlisting>
+ <para><literal>foo</literal> returns two compiled closures. The first closure increments <replaceable>x</replaceable>
+ by one, whereas the second closure increments <replaceable>x</replaceable> by the initial value of
+ <replaceable>x</replaceable>. Both closures return the incremented value of <replaceable>x</replaceable>.</para>
+ <para><screen>
+ >(multiple-value-setq (f g) (foo 10))
+ #<compiled-closure nil>
+
+ >(funcall f)
+ 11
+
+ >(funcall g)
+ 21
+
+ >
+ </screen></para>
+ <para>After this, the two compiled closures look like:</para>
+ <screen><![CDATA[
+ second closure y: x:
+ |-------|------| |-------|------| |------|------|
+ | ** | --|----->| 10 | --|------>| 21 | nil |
+ |-------|------| |-------|------| |------|------|
+ ^
+ first closure |
+ |-------|------| |
+ | * | --|----------|
+ |-------|------|
+
+ * : address of the compiled code for #'(lambda () (incf x))
+ ** : address of the compiled code for #'(lambda () (incf x y))
+ ]]></screen>
+ </section>
+
+ <section xml:id="Internals-Use-of-Declarations-to-Improve-Efficiency">
+ <title>Use of Declarations to Improve Efficiency</title>
+ <para>Declarations, especially type and function declarations,
+ increase the efficiency of the compiled code. For example, for the
+ following Lisp source file, with two Common-Lisp declarations added,</para>
+ <programlisting>
+ (eval-when (compile)
+ (proclaim '(function tak (fixnum fixnum fixnum) fixnum))
+
+ (defun tak (x y z)
+ (declare (fixnum x y z))
+ (if (not (< y x))
+ z
+ (tak (tak (1- x) y z)
+ (tak (1- y) z x)
+ (tak (1- z) x y))))
+ </programlisting>
+ <para>The compiler generates the following C code:</para>
+ <screen>
+ /* local entry for function TAK */
+ static int LI1(register int V1,register int V2,register int V3)
+ { VT3 VLEX3 CLSR3
+ TTL:
+ if (V2 < V1) {
+ goto L2;}
+ return(V3);
+ L2:
+ { int V5;
+ V5 = LI1((V1)-1,V2,V3);
+ { int V6;
+ V6 = LI1((V2)-1,V3,V1);
+ V3 = LI1((V3)-1,V1,V2);
+ V2 = V6;
+ V1 = V5;}}
+ goto TTL;
+ ;;; Note: Tail-recursive call of TAK was replaced by iteration.
+ }
+ </screen>
+ </section>
+
+ <section xml:id="Internals-Inspecting-generated-C-code">
+ <title>Inspecting generated C code</title>
+ <para>Common-Lisp defines a function disassemble, which is
+ supposed to disassemble a compiled function and to display the
+ assembler code. According to <emphasis>Common-Lisp: The Language</emphasis>,</para>
+
+ <para><emphasis>This is primary useful for debugging the compiler</emphasis>, ..\\</para>
+ <!-- FIXME: Actually disassemble shows bytecode -->
+ <para>This is, however, <emphasis>useless</emphasis> in our case, because we are
+ not concerned with assembly language. Rather, we are interested in
+ the C code generated by the &ECL; compiler. Thus the disassemble
+ function in &ECL; accepts not-yet-compiled functions only and displays
+ the translated C code.</para>
+ <para><screen>
+ > (defun add1 (x) (1+ x))
+ ADD1
+ > (disassemble *)
+ ;;; Compiling (DEFUN ADD1 ...).
+ ;;; Emitting code for ADD1.
+
+ /* function definition for ADD1 */
+ static L1(int narg, object V1)
+ { VT3 VLEX3 CLSR3
+ TTL:
+ VALUES(0) = one_plus((V1));
+ RETURN(1);
+ }
+ </screen></para>
+ </section>
+</chapter>
+
+<chapter xml:id="Porting-ECL">
+ <title>Porting &ECL;</title>
+ <para>To port &ECL; to a new architecture, the following steps are required:</para>
+ <orderedlist numeration="arabic">
+ <listitem>
+ <para>Ensure that the GNU Multiprecision library supports this machine.</para>
+ </listitem>
+ <listitem>
+ <para>Ensure that the Boehm-Weiser garbage collector is supported by that
+ architecture. Alternatively, port ECL's own garbage collector
+ <filename>src/c/alloc.d</filename> and <filename>src/c/gbc.d</filename> to
+ that platform.</para>
+ </listitem>
+ <listitem>
+ <para>Fix <filename>src/aclocal.in</filename>,
+ <filename>src/h/config.h.in</filename> and
+ <filename>src/h/ecl.h</filename> so that they supply flags for the new
+ host machine.</para>
+ </listitem>
+ <listitem>
+ <para>Fix the machine dependent code in <filename>src/c/</filename>. The
+ most critical parts are in the <filename>unix*.d</filename> and
+ <filename>thread*.d</filename> files.</para>
+ </listitem>
+ <listitem>
+ <para>Compile as in any other platform.</para>
+ </listitem>
+ <listitem>
+ <para>Run the tests and compare to the results of other platforms.</para>
+ </listitem>
+ </orderedlist>
+</chapter>
+</part></book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+-->
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="The-interpreter">
+<title>The Interpreter</title>
+<para>Former versions of &ECL;, as well as many other lisps, used linked lists to
+represent code. As of version 0.3 a bytecodes compiler and a bytecodes
+interpreter were developed to circumvent the limitations of linked lists.</para>
+<para>When you enter code at the lisp prompt, or when you load a source file,
+&ECL; begins a process known as minimal compilation. Barely this
+process consists on parsing each form, macroexpanding it and translating
+it into an intermediate language made of <emphasis>bytecodes</emphasis>.</para>
+<para>The bytecodes compiler is implemented in <filename>src/c/compiler.d</filename>. The main
+entry point is the lisp function <literal>SI::MAKE-LAMBDA</literal>, which takes a
+name for the function and the body of the lambda lists, and produces a
+lisp object that can be invoked. For instance,</para>
+<para><screen>
+> (defvar fun (si::make-lambda 'f '((x) (1+ x))))
+*FUN*
+> (funcall fun 2)
+3
+</screen></para>
+<para>&ECL; can only execute bytecodes. When a list is passed to <literal>EVAL</literal> it
+must be first compiled to bytecodes and, if the process succeeds, then the
+resulting bytecodes are passed to the interpreter. Similarly, every time a
+function object is created, such as in <literal>DEFUN</literal> or <literal>DEFMACRO</literal>, the
+bytecodes compiler processes the lambda form to produce a suitable bytecodes
+object.</para>
+<para>The fact that &ECL; performs this eager compilation means that changes on
+a macro are not immediately seen in code which was already compiled. This has
+subtle implications. Take the following code:<screen>
+> (defmacro f (a b) `(+ ,a ,b))
+F
+> (defun g (x y) (f x y))
+G
+> (g 1 2)
+3
+> (defmacro f (a b) `(- ,a ,b))
+F
+> (g 1 2)
+3
+</screen></para>
+<para role="continues">The last statement always outputs <literal>3</literal> while in former
+implementations based on processing of lambda lists it would produce <literal>-1</literal>.</para>
+</chapter>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+--></book>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <preface xml:id="preface">
+ <title>Preface</title>
+
+ <section xml:id="preface.words">
+ <title>About this book</title>
+
+ <para>This manual is part of the &ECL; software system. It documents
+ deviations of &ECL; from the &ANSI; standard, as well as extensions, daily
+ working process (compiling files, loading sources, creating programs, etc)
+ and the internals of this implementation.</para>
+
+ <para>This book is not intended as a source to learn &CommonLisp;. There are
+ other tutorials and textbooks available in the Net which serve this
+ purpose. The homepage of the <ulink url="http://www.lisp.org">Association of
+ Lisp Users</ulink> contains a good list of links of such teaching and
+ learning material.</para>
+
+ <para>This book is structured into three parts. We begin with <xref
+ linkend="part.standards"/> documents all parts of the standard which are left as
+ <emphasis>implementation specific</emphasis>. For instance, precision of
+ floating point numbers, available character sets, actual input/output
+ protocols, etc.</para>
+
+ <para><xref linkend="part.extensions"/> introduces all features which are
+ specific to &ECL; and which lay outside the standard. This includes
+ configuring, building and installing &ECL; multiprocessing capabilities,
+ graphics libraries, interfacing with the operating system, etc.</para>
+
+ <para><xref linkend="part.internals"/> deals with the internals of the
+ implementation. This part is only intended for experienced programmers that
+ want to learn how &ECL; does its work and wish to extend it, customize it or
+ port it to new architectures. This part of the documentation is the most
+ fragile one and prone to change.</para>
+
+ <important><para>Missing highlights</para></important>
+ </section>
+
+ <section xml:id="preface.what.is.ecl">
+ <title>What is &ECL;?</title>
+
+ <para>&ECL; is an implementation of the Common-Lisp language that was
+ developed by Giuseppe Attardi's up from the Kyoto Common-Lisp. See <xref
+ linkend="preface.credits"></xref> for the history of the code you are up to
+ use.</para>
+
+ <para>&ECL; (ECL for short) uses standard C calling conventions for Lisp
+ compiled functions, which allows C programs to easily call Lisp functions
+ and vice versa. No foreign function interface is required: data can be
+ exchanged between C and Lisp with no need for conversion.</para>
+
+ <para>&ECL; is based on a Common Runtime Support (CRS) which provides basic
+ facilities for memory management, dynamic loading and dumping of binary
+ images, support for multiple threads of execution. The CRS is built into a
+ library that can be linked with the code of the application. &ECL; is
+ modular: main modules are the program development tools (top level,
+ debugger, trace, stepper), the compiler, and CLOS. A native implementation
+ of CLOS is available in &ECL;: one can configure &ECL; with or without CLOS.
+ A runtime version of &ECL; can be built with just the modules which are
+ required by the application.</para>
+
+ <para>The &ECL; compiler compiles from Lisp to C, and then invokes
+ the GNU C compiler to produce binaries. While former releases of ECL
+ adhere to the the reference of the language given in &Steele84;, the
+ aim of &ECL; is now to achieve maximum compliance with ANSI
+ Common-Lisp, the most up to date standard for Common-Lisp.</para>
+ <para>Throughout this manual we will describe the &ECL; implementation and
+ how it differs from &ANSI; and &Steele84;. In general, as
+ work in &ECL; is completed section by section, we will drop compatibility
+ with &Steele84; and the corresponding chapter will be updated to
+ document <emphasis>only</emphasis> the differences with &ANSI;.</para>
+
+ <section xml:id="Credits">
+ <title>Credits</title>
+ <para>The &ECL; project is an implementation of the Common-Lisp language that aims to
+ comply with the ANSI Common-Lisp standard. The first ECL implementations were developed
+ by Giuseppe Attardi's who produced an interpreter and compiler fully conformat
+ with the Common-Lisp as reported in <citetitle>Steele:84</citetitle>. ECL derives itself mostly
+ from Kyoto Common-Lisp, an implementation developed at the Research Institute for
+ Mathematical Sciences (RIMS), Kyoto University, with the cooperation of Nippon
+ Data General Corporation. The main developers of Kyoto Common-Lisp were Taiichi
+ Yuasa and Masami Hagiya, of the Research Institute for Mathematical Sciences,
+ at Kyoto University.</para>
+ <para>I must thank Giuseppe Attardi, Yuasa and Hagiya for their wonderful work with
+ preceding implementations and for putting them in the Public Domain under the
+ GNU General Public License as published by the Free Software Foundation.
+ Without them this product would have never been possible.</para>
+ <para>This document is an update of the original ECL documentation, which was based
+ in part on the material in [Yuasa:85, see <xref linkend="Bibliography"></xref>]</para>
+ <para>The following people or organizations must be credited for support in the
+ development of Kyoto Common-Lisp: Prof. Reiji Nakajima at RIMS, Kyoto University;
+ Nippon Data General Corporation; Teruo Yabe; Toshiyasu Harada; Takashi Suzuki;
+ Kibo Kurokawa; Data General Corporation; Richard Gabriel; Daniel Weinreb; Skef
+ Wholey; Carl Hoffman; Naruhiko Kawamura; Takashi Sakuragawa; Akinori Yonezawa;
+ Etsuya Shibayama; Hagiwara Laboratory; Shuji Doshita; Takashi Hattori.</para>
+ <para>William F. Schelter improved KCL in several areas and developed Austin Kyoto
+ Common-Lisp (AKCL). Many ideas and code from AKCL have been incorporated in
+ &ECL;.</para>
+ <para>The following is the full list of contributors to ECL: Taiichi Yuasa and
+ Masami Hagiya (KCL), William F. Schelter (Dynamic loader, conservative Gc),
+ Giuseppe Attardi (Top-level, trace, stepper, compiler, CLOS, multithread),
+ Marcus Daniels (Linux port) Cornelis van der Laan (FreeBSD port) David Rudloff
+ (NeXT port) Dan Stanger, Don Cohen, and Brian Spilsbury.</para>
+ <para>We have to thank for the following pieces of software that have helped in the
+ development of &ECL;</para>
+ <variablelist>
+ <varlistentry>
+ <term>Bruno Haible</term>
+ <listitem>
+ <para>For the Cltl2-compliance test</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Peter Van Eynde</term>
+ <listitem>
+ <para>For the ANSI-compliance test</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Symbolic's Inc.</term>
+ <listitem>
+ <para>For the ANSI-compliant LOOP macro.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>The &ECL; project also owes a lot to the people who have tested this program
+ and contributed with suggestions and error messages: Eric Marsden, Hannu
+ Koivisto and Jeff Bowden, and others whose name I may have omitted.</para>
+ </section>
+
+ <section xml:id="Copyright">
+ <title>Copyright</title>
+ <para role="continues">Copyright © 2000 Juan Jose Garcia Ripoll</para>
+ <para role="continues">Copyright © 1990, 1991, 1993 Giuseppe Attardi</para>
+ <para role="continues">Copyright © 1984 Taiichi Yuasa and Masami Hagiya</para>
+ <para role="continues">All Rights Reserved</para>
+ <para role="continues">Summary:</para>
+ <blockquote>
+ <para>Permission is granted to use, copy, modify this program,
+ EXCEPT that the copyright notice must be reproduced on copies, and
+ credit should be given to the authors where it is due.
+ WE MAKE NO WARRANTY AND ACCEPT NO LIABILITY FOR THIS PROGRAM.</para>
+ </blockquote>
+ <para role="continues">In detail:</para>
+ <orderedlist numeration="arabic">
+ <listitem>
+ <para>Permission to use, copy, modify this software and its documentation
+ for any purpose is hereby granted without fee, provided that</para>
+ <itemizedlist mark="bullet">
+ <listitem>
+ <para>the above copyright notice appears in all copies,</para>
+ </listitem>
+ <listitem>
+ <para>both that copyright notice and this permission notice appears in supporting documentation, and that</para>
+ </listitem>
+ <listitem>
+ <para>you cause modified files to carry prominent notices stating that you changed the files and the date of any change.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ <listitem>
+ <para>Please notify us if you are going to sell this software or its documentation
+ for profit.</para>
+ </listitem>
+ <listitem>
+ <para>WE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL WE BE LIABLE FOR
+ ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
+ USE OR PERFORMANCE OF THIS SOFTWARE.</para>
+ </listitem>
+ </orderedlist>
+ <para role="continues">Additionally:</para>
+ <blockquote>
+ <para>&ECL; is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version; see file 'Copying'.</para>
+ <para>This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.</para>
+ <para>You should have received a copy of the GNU Library General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.</para>
+ </blockquote>
+ <para role="continues">Address for reporting bugs, comments, suggestions:</para>
+ <blockquote>
+ <para><ulink url="mailto:worm@@arrakis.es"></ulink></para>
+ </blockquote>
+ </section>
+
+ <section xml:id="Building-ECL">
+ <title>Building ECL</title>
+ <orderedlist numeration="arabic">
+ <listitem>
+ <para>Obtain the distribution from <ulink url="http://ecls.sourceforge.net">http://ecls.sourceforge.net</ulink>.
+ The distribution is in a gzip-compressed tar file named like
+ <filename>ecl.tgz</filename></para>
+ </listitem>
+ <listitem>
+ <para>Prepare a directory (hereafter called <firstterm>ECL directory</firstterm>) for
+ ECL. In the following examples, we suppose that the <emphasis>ECL
+ directory</emphasis> is <filename>/usr/local/ecl</filename>.</para>
+ </listitem>
+ <listitem>
+ <para>Extract the content from the compressed tar file.<screen>
+ $ zcat ecl.tgz | tar xf -
+ </screen></para>
+ </listitem>
+ <listitem>
+ <para>An auto configuration mechanism allows you to perform a standard
+ installation with the following commands:<screen>
+ $ ./configure
+ </screen>This example will prepare to install executable files, manual pages and
+ info files in standard directories like <filename>/usr/local/bin</filename>,
+ <filename>/usr/local/man/man1</filename>, <filename>/usr/local/info</filename>.</para>
+ </listitem>
+ <listitem>
+ <para>If you don't have access rights to these directories, you should
+ give to configure alternate places. Try <literal>./configure --help</literal> for
+ instructions on how to supply this information to configure, but
+ a good starting point is<screen>
+ $ ./configure --prefix=$HOME
+ </screen></para>
+ </listitem>
+ <listitem>
+ <para>Next you must build the program and install it<screen>
+ $ make
+ $ make install
+ </screen></para>
+ </listitem>
+ </orderedlist>
+ <para>At the end of installation, the destination directories will contain
+ several files. If you have not modified these directories when
+ invoking <filename>configure</filename> the layout should be</para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colwidth="50*"></colspec>
+ <colspec colwidth="50*"></colspec>
+ <tbody>
+ <row>
+ <entry><emphasis role="bold">Executable files:</emphasis></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><filename>$HOME/bin/ecl</filename></entry>
+ <entry>the &ECL; interpreter and compiler</entry>
+ </row>
+ <row>
+ <entry><emphasis role="bold">Help documents:</emphasis></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><filename>$HOME/lib/ecl/help.doc</filename></entry>
+ <entry>data for the online help</entry>
+ </row>
+ <row>
+ <entry><filename>$HOME/man/man1/ecl.1</filename></entry>
+ <entry>manual page for &ECL;</entry>
+ </row>
+ <row>
+ <entry><filename>$HOME/info/ecl.info</filename></entry>
+ <entry>this manual you are reading</entry>
+ </row>
+ <row>
+ <entry><emphasis role="bold">Library files and headers:</emphasis></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><filename>$HOME/lib/ecl/libecl.a</filename></entry>
+ <entry>the core library in C</entry>
+ </row>
+ <row>
+ <entry><filename>$HOME/lib/ecl/libgmp.a</filename></entry>
+ <entry>GNU library for bignums</entry>
+ </row>
+ <row>
+ <entry><filename>$HOME/lib/ecl/libgc.a</filename></entry>
+ <entry>Boehm-Weiser garbage collector</entry>
+ </row>
+ <row>
+ <entry><filename>$HOME/lib/ecl/*.a</filename></entry>
+ <entry>Other lisp compiled code</entry>
+ </row>
+ <row>
+ <entry><filename>$HOME/lib/ecl/ecl/</filename></entry>
+ <entry>Header files</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ <para>You can remove all intermediate files produced during installation with the
+ command <literal>make clean</literal>.</para>
+ </section>
+
+ <section xml:id="Invoking-ECL">
+ <title>Entering and leaving &ECL;</title>
+ <para>&ECL; is invoked by the command <literal>ecl</literal>.</para>
+ <para><screen>
+ % ecl
+ ECL (Embeddable Common-Lisp) 0.0e
+ Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
+ Copyright (C) 1993 Giuseppe Attardi
+ Copyright (C) 2000 Juan J. Garcia-Ripoll
+ ECL is free software, and you are welcome to redistribute it
+ under certain conditions; see file 'Copyright' for details.
+ Type :h for Help. Top level.
+ >
+ </screen></para>
+ <para>When invoked, &ECL; will print the banner and initialize the system. The
+ date in the &ECL; banner identifies the revision of &ECL;. <literal>Version
+ (0.8) 05/14/1993</literal> is the value of the function
+ <literal>lisp-implementation-version</literal>.</para>
+ <para>If there exists a file named <filename>init.lsp</filename> in the current working directory,
+ &ECL; successively evaluates the forms in the file, immediately after the
+ system initialization. The user may set up his or her own &ECL; environment
+ (e.g., the memory configuration) with <filename>init.lsp</filename>.</para>
+ <para>After the initialization, &ECL; enters the <firstterm>top-level loop</firstterm> and prints
+ the prompt `<literal>></literal>'.</para>
+ <para><screen>
+ Type :h for Help. Top level.
+ >
+ </screen></para>
+ <para>The prompt indicates that &ECL; is now ready to receive a form from the
+ terminal and to evaluate it.</para>
+ <para>Usually, the current package (i.e., the value of <replaceable>*package*</replaceable>) is the user
+ package, and the prompt appears as above. If, however, the current package is
+ other than the user package, then the prompt will be prefixed by the package
+ name.</para>
+ <para><screen>
+ > (in-package 'cl)
+ #<"COMMON-LISP" package>
+ COMMON-LISP> (in-package 'system)
+ #<"SYSTEM" package>
+ SYSTEM>
+ </screen></para>
+ <para>To exit from &ECL;, call the function <literal>quit</literal>.</para>
+ <para><screen>
+ >(quit)
+ Bye.
+ %
+ </screen></para>
+ <para>Alternatively, you may type ^D, i.e. press the key <keycap>D</keycap> while pressing
+ down the control key (<keycap>Ctrl</keycap>).</para>
+ <para><screen>
+ >^DBye.
+ %
+ </screen></para>
+ <para>You can disable ^D as the exit command by setting to <literal>T</literal> the
+ following variable:</para>
+ <blockquote>
+ <screen><indexterm role="vr"><primary>*ignore-eof-on-terminal-io*</primary></indexterm>— System: <varname>*ignore-eof-on-terminal-io*</varname></screen>
+ <para>This variable controls whether an end of file character (normally ^D)
+ should terminate the session. The default value is ().</para>
+ </blockquote>
+ <para>The top-level loop of &ECL; is almost the same as that defined in Section
+ 20.2 of &Steele84;. Since the input from the terminal is in line
+ mode, each top-level form should be followed by a newline. If more than one
+ value is returned by the evaluation of the top-level form, the values will be
+ printed successively. If no value is returned, then nothing will be printed.<screen>
+ >(values 1 2)
+ 1
+ 2
+ >(values)
+
+ >
+ </screen></para>
+ <para>When an error is signalled, control will enter the break loop.<screen>
+ >(defun foo (x) (bar x))
+ foo
+
+ >(defun bar (y) (bee y y))
+ bar
+
+ >(foo 'lish)
+ Error: The function BEE is undefined.
+ Error signalled by BAR.
+
+ Broken at BAR.
+ >>
+ </screen></para>
+ <para>`<literal>>></literal>' in the last line is the prompt of the break loop. Like in the
+ top-level loop, the prompt will be prefixed by the current package name, if the
+ current package is other than the <literal>user</literal> package.</para>
+ <para>To go back to the top-level loop, type <literal>:q</literal></para>
+ <para><screen>
+ >>:q
+
+ Top level.
+ >
+ </screen></para>
+ <para>See Section 5.4 for the details of the break loop.</para>
+ <para>The terminal interrupt (usually caused by typing ^C (Control-<literal>C</literal>))
+ is a kind of error. It breaks the running program and calls the break level
+ loop.</para>
+ <para>Example:<screen>
+ >(defun foo () (do () (nil)))
+ foo
+
+ >(foo)
+ ^C
+ Correctable error: Console interrupt.
+ Signalled by DO.
+
+ Broken at FOO.
+ >>
+ </screen></para>
+ </section>
+ </preface>
+ </book>
+ <!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent:1
+ fill-column: 79
+ End:
+ -->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="Input-and-output">
+<title>Input and Output</title>
+<section xml:id="Read-macros">
+<title>Read macros</title>
+<variablelist>
+<varlistentry>
+<term>#P"</term>
+<listitem>
+<para><literal>#"<replaceable>string</replaceable>"</literal> reads a pathname. <literal>#"<replaceable>string</replaceable>"</literal> is equivalent
+to <literal>(pathname "<replaceable>string</replaceable>")</literal>.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>#$</term>
+<listitem>
+<para><literal>#$<replaceable>integer</replaceable></literal> reads a random state. <literal>#$</literal><replaceable>integer</replaceable> is
+equivalent to <literal>(make-random-state <replaceable>integer</replaceable>)</literal>.</para>
+</listitem>
+</varlistentry>
+</variablelist>
+<para>The <literal>#</literal> macro '<literal>#,</literal>' works as described in &Steele84;, only
+if it is included in a constant object. The forms immediately after
+<literal>`#,'</literal> below will be evaluated when the compiled code is loaded.</para>
+<screen>
+'#,x
+'(a b c (d #,e f) g)
+#(1 2 3 #,(+ a b c) 5 6)
+#C(0.0 #,(exp 1))
+</screen>
+<para>Otherwise, the effect of using '<literal>#,</literal>' is unpredictable. Note that, when
+interpreted code is loaded, '<literal>#,</literal>' has the same effect as the <literal>#</literal>
+macro '<literal>#.</literal>'.</para>
+</section>
+
+<section xml:id="Input-Output-functions">
+<title>Input and Output Functions</title>
+<para>The input and output functions of &ECL; almost follow the definitions in
+Chapter 22 of &Steele84;. Most of the differences come from the fact
+that, in &ECL;, input from the terminal is always in line mode and binary I/O
+is not supported.</para>
+<para>In &ECL;, <literal>*terminal-io*</literal> is a two-way stream from the standard input
+and to the standard output. The echoing to the terminal is performed by the
+underlying operating system. In particular, when a disk file is assigned to
+the standard output, nothing will be echoed at the terminal.</para>
+<para>Those functions that deviate from the definitions in &Steele84; are
+listed below.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>load</primary></indexterm>— Function: <function>load</function> <varname>pathname &key :print :verbose :if-does-not-exist</varname></screen>
+<para>If <replaceable>pathname</replaceable> does not specify the filetype of the input file, then load
+uses the association list <replaceable>si::*load-search-list*</replaceable> to find out a suitable
+filetype and the function to load it. Typically, this search list is made of
+the elements <literal>.fas</literal>, <literal>.lsp</literal> and <literal>.lisp</literal>, in this order. If
+everything fails, a file without filetype will be loaded.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>open</primary></indexterm>— Function: <function>open</function> <varname></varname></screen>
+<para>Streams can only have element type <literal>base-char</literal>, <literal>(signed-byte 8)</literal>
+and <literal>(unsigned-byte 8)</literal>. The <literal>:external-format</literal> is always <literal>:default</literal>.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>close</primary></indexterm>— Function: <function>close</function> <varname></varname></screen>
+<para>The keyword variable <replaceable>:abort</replaceable> is always ignored.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>listen</primary></indexterm>— Function: <function>listen</function> <varname></varname></screen>
+<para>This routine requires some low level functions which are not available on
+all platforms (For instance on <literal>Windows</literal>). When ECL is not able to
+determine whether a stream is interactive, <literal>listen</literal> returns true unless
+an end of file has been previously detected.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>clear-input</primary></indexterm>— Function: <function>clear-input</function> <varname></varname></screen>
+<para>The functions <literal>clear-input</literal> and <literal>clear-output</literal> do nothing.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>read-char-no-hang</primary></indexterm>— Function: <function>read-char-no-hang</function> <varname></varname></screen>
+<para><literal>read-char-no-hang</literal> is equivalent to <literal>read-char</literal>.</para>
+</blockquote>
+<para>The functions <literal>princ</literal>, <literal>write-char</literal> and <literal>write-byte</literal> do not
+always flush the stream. The stream is flushed when</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>a newline character is written, or</para>
+</listitem>
+<listitem>
+<para>the input from the terminal is requested in the case that these
+functions operate on <literal>*terminal-io*</literal></para>
+</listitem>
+</orderedlist>
+</section>
+
+<section xml:id="Network-streams">
+<title>Network Streams</title>
+<para>With a configuration option, the following function is available which opens
+streams across network connections.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>open-client-stream</primary></indexterm>— Function: <function>open-client-stream</function> <varname>host port</varname></screen>
+<para>The string <replaceable>host</replaceable> indicates the name of the host, while <replaceable>port</replaceable> is an
+integer which identifies the port number to which to connect. This function
+returns a two-way stream which can be used in any of the stream operations.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>open-server-stream</primary></indexterm>— Function: <function>open-server-stream</function> <varname>host port</varname></screen>
+<para>A stream connected to port number <replaceable>port</replaceable> is created to which clients can
+connect. This function returns a two-way stream which can be used in any of
+the stream operations.</para>
+</blockquote>
+</section>
+
+<section xml:id="CLOS-streams">
+<title>CLOS Streams</title>
+<para>When the optional CLOS subsystem is available, an interface is provided by
+&ECL; for using CLOS objects as Common-Lisp input/output character streams.
+Such support can be used for instance to build interactive character streams,
+which may be used by applications as the stream argument for Common-Lisp I/O
+functions such as <literal>read</literal>, <literal>listen</literal>, <literal>prin1</literal>, etc. The
+fundamental interface to <literal>clos-stream</literal> objects consists of
+(generic) functions which implement the basic Common-Lisp character stream
+operations (see Common-Lisp, Chapter 22) but whose details are implementation
+dependent.</para>
+<para>The following functions are automatically invoked by &ECL; when a stream
+operation involves a CLOS object as a stream parameter. The programmer should
+define these methods for any class of objects which are to be used for
+character input/output.</para>
+
+<section xml:id="CLOS-Stream-Input">
+<title>CLOS Stream Input</title>
+<para>Character input from an <literal>clos-stream</literal> is implemented by the
+following methods.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>stream-read-char</primary></indexterm>— Method: <function>stream-read-char</function> (<varname>object</varname> <varname>clos-stream</varname>)</screen>
+<para>Returns the next character object read from the CLOS stream <replaceable>object</replaceable>.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>stream-unread-char</primary></indexterm>— Method: <function>stream-unread-char</function> (<varname>object</varname> <varname>clos-stream</varname>) <varname>character</varname></screen>
+<para>Unreads the character object <replaceable>character</replaceable> from the CLOS stream <replaceable>object</replaceable>.
+<replaceable>character</replaceable> will be the next character read by <literal>stream-read-char</literal>.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>stream-listen</primary></indexterm>— Method: <function>stream-listen</function> (<varname>object</varname> <varname>clos-stream</varname>)</screen>
+<para>Returns () is no character is immediately available from the CLOS stream
+<replaceable>object</replaceable>. Otherwise, the next character is returned, as if
+<literal>stream-peek-char</literal> had been called.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>stream-clear-input</primary></indexterm>— Method: <function>stream-clear-input</function> <varname>object</varname></screen>
+<para>Clears any buffered characters on the CLOS stream <replaceable>object</replaceable>. Returns ().</para>
+</blockquote>
+</section>
+
+<section xml:id="CLOS-Stream-Output">
+<title>CLOS Stream Output</title>
+<para>Character output from an <literal>clos-stream</literal> is implemented by the
+following methods.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>stream-write-char</primary></indexterm>— Method: <function>stream-write-char</function> (<varname>object</varname> <varname>clos-stream</varname>) <varname>character</varname></screen>
+<para>Outputs the character <replaceable>character</replaceable> to the CLOS stream <replaceable>object</replaceable> and
+returns it.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>stream-clear-output</primary></indexterm>— Method: <function>stream-clear-output</function> (<varname>object</varname> <varname>clos-stream</varname>)</screen>
+<para>Aborts any outstanding output operation on the CLOS stream <replaceable>object</replaceable> and
+returns ().</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>stream-force-output</primary></indexterm>— Method: <function>stream-force-output</function> (<varname>object</varname> <varname>clos-stream</varname>)</screen>
+<para>Initiates the emptying of the internal buffers on the CLOS stream <replaceable>object</replaceable>
+and returns ().</para>
+</blockquote>
+</section>
+
+<section xml:id="CLOS-Stream-common">
+<title>CLOS Stream common</title>
+<para>The following functions should be available for all CLOS streams.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>stream-interactive-p</primary></indexterm>— Method: <function>stream-interactive-p</function> (<varname>object</varname> <varname>clos-stream</varname>)</screen>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>stream-close</primary></indexterm>— Method: <function>stream-close</function> (<varname>object</varname> <varname>clos-stream</varname>)</screen>
+<para>Closes the stream for any further input or output.</para>
+</blockquote>
+</section>
+</section>
+</chapter>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent:1
+ fill-column: 79
+ End:
+--></book>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="Macros">
+<title>Macros</title>
+<para>A <firstterm>defmacro lambda-list</firstterm> is a lambda-list-like construct that is used as
+the third element in the <literal>defmacro</literal> form,</para>
+<screen>
+(defmacro <replaceable>name</replaceable> <replaceable>efmacro-lambda-list</replaceable> [<replaceable>declaration</replaceable> | <replaceable>doc-string</replaceable>] {<replaceable>form</replaceable>}*)
+</screen>
+<para>The description of defmacro lambda-lists in &Steele84; is quite
+ambiguous. &ECL; employs the following syntax.</para>
+<para>The complete syntax of a defmacro lambda-list is:</para>
+<screen>
+( [&whole <replaceable>var</replaceable>]
+[&environment <replaceable>var</replaceable>]
+[<replaceable>pseudo-var</replaceable>]
+[&optional {var | ( pseudo-var [initform [pseudo-var]] )}]
+{[{&rest | &body} pseudo-var]
+[&key {var
+| ({var | (keyword pseudo-var)} [initform [pseudo-var]])}*
+[&allow-other-keys]]
+[&aux {var | (pseudo-var [initform])}*]
+| . var }
+)
+</screen>
+<para role="continues">where <replaceable>pseudo-var</replaceable> is either a symbol or a list of the following
+form:</para>
+<screen>
+( {pseudo-var}*
+[&optional {var | (pseudo-var [initform [pseudo-var]])}*]
+{[{&rest | &body} pseudo-var]
+[&key {var | ({var | (keyword pseudo-var)}
+[initform [pseudo-var]])}*
+[&allow-other-keys]]
+[&aux {var | (pseudo-var [initform])}]
+| . var }
+)
+</screen>
+<para>The defmacro lambda-list keyword <literal>&whole</literal> may appear only at the
+top-level, first in the defmacro lambda-list. It is not allowed within
+<replaceable>pseudo-var</replaceable>. Use of the <literal>&whole</literal> keyword does not affect the
+processing of the rest of the defmacro lambda-list:</para>
+<programlisting>
+(defmacro foo (&whole w x y) ...)
+</programlisting>
+<para>and</para>
+<programlisting>
+(defmacro foo (x y) ...)
+</programlisting>
+<para role="continues">both bind the variables <literal>x</literal> and <literal>y</literal> to the second and the
+third elements, respectively, of macro forms of <literal>foo</literal>.</para>
+<para>The defmacro lambda-list keyword <literal>&environment</literal> may appear only at the
+top-level, first in the defmacro lambda-list if <literal>&whole</literal> is not supplied,
+or immediately after the variable that follows <literal>&whole</literal>, if <literal>&whole</literal>
+is supplied. <literal>&environment</literal> is not allowed within <replaceable>pseudo-var</replaceable>. Like
+<literal>&whole</literal>, use of <literal>&environment</literal> does not affect the processing of the
+rest of the defmacro lambda-list. If an <literal>&environment</literal> parameter is
+supplied and if this parameter is not used at all, then the &ECL; compiler
+will issue a warning. To suppress the warning, just remove the parameter from
+the defmacro lambda-list, or add an <literal>ignore</literal> declaration.</para>
+<para>The defmacro lambda-list keyword <literal>&body</literal> is completely equivalent to the
+&rest keyword. &ECL; takes no special action for <literal>&body</literal> parameters.</para>
+<para>Although useless, &ECL; allows supplied-p parameters to be destructured.
+This is useless because supplied-p parameters can never be bound to a non-empty
+list. Our intention is to stick to the specification in the
+&Steele84; as far as possible, even if it is silly to do so.</para>
+<para>Like for ordinary lambda-lists, the interpreter detects invalid arguments to
+macro expansion functions. When a parameter is destructured, the structure of
+the corresponding argument is also checked. Such runtime argument checking may
+or may not be embedded in compiled code, depending on the environment when the
+code was generated. If the code was generated while the <literal>safety</literal> optimize
+level is zero (that is, while the value of <literal>(proclamation '(optimize
+(safety 0)))</literal> is <replaceable>T</replaceable>), then the generated code does not perform argument
+checking at all. Otherwise, the compiled code does check the validity of
+arguments.</para>
+</chapter>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+--></book>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <chapter xml:id="ext.memory">
+ <title>Memory Management</title>
+
+ <section xml:id="ext.memory.intro">
+ <title>Introduction</title>
+
+ <para>&ECL; relies on the Boehm-Weiser garbage collector for handling
+ memory, creating and destroying objects, and handling finalization of
+ objects that are no longer reachable. The use of a garbage collector, and in
+ particular the use of a portable one, imposes certain restrictions that may
+ appear odd for C/C++ programmers.</para>
+
+ <para>In this section we will discuss garbage collection, how &ECL;
+ configures and uses the memory management library, what users may expect,
+ how to handle the memory and how to control the process by which objects are
+ deleted.</para>
+
+ </section>
+
+ <section xml:id="ext.memory.boehm">
+ <title>Boehm-Weiser garbage collector</title>
+
+ <para>First of all, the garbage collector must be able to determine which
+ objects are alive and which are not. In other word, the collector must able
+ to find all references to an object. One possiblity would be to know where
+ all variables of a program reside, and where is the stack of the program and
+ its size, and parse all data there, discriminating references to lisp
+ objects. To do this precisely one would need a very precise control of the
+ data and stack segments, as well as how objects are laid out by the C
+ compiler. This is beyond &ECL;'s scope and wishes and it can make
+ coexistence with other libraries (C++, Fortran, etc) difficult.</para>
+
+ <para>The Boehm-Weiser garbage collector, on the other hand, is a
+ conservative garbage collector. When scanning memory looking for references
+ to live data, it guesses, conservatively, whether a word is a pointer or
+ not. In case of doubt it will consider it to be a pointer and add it to the
+ list of live objects. This may cause certain objects to be retained longer
+ than what an user might expect but, in our experience, this is the best of
+ both worlds and &ECL; uses certain strategies to minimize the amount of
+ misinterpreted data.</para>
+
+ <para>More precisely, &ECL; uses the garbage collector with the following
+ settings:</para>
+ <itemizedlist>
+ <listitem><para>The collector will not scan the data sectors. If you embed
+ &ECL; in another program, or link libraries with &ECL;, you will have to
+ notify &ECL; which variables point to lisp objects.</para></listitem>
+
+ <listitem><para>The collector is configured to ignore pointers that point
+ to the middle of allocated objects. This minimizes the risk of
+ misinterpreting integers as pointers to live obejcts.</para></listitem>
+
+ <listitem><para>It is possible to register finalizers that are invoked when
+ an object is destroyed, but for that you should use &ECL;'s API and
+ understand the restriction described later in <xref
+ linkend="ext.memory.finalization" xrefstyle="select: label"/></para></listitem>
+ </itemizedlist>
+
+ <para>Except for finalization, which is a questionable feature, the previous
+ settings are not very relevant for &CommonLisp; programmers, but are crucial
+ for people interested in embedding in or cooperating with other C, C++ or
+ Fortran libraries. Care should be taken when manipulating directly the GC
+ library to avoid interfering with &ECL;'s expectations.</para>
+ </section>
+
+ <section xml:id="ext.memory.limits">
+ <title>Memory limits</title>
+
+ <para>Beginning with version 9.2.1, &ECL; operates a tighter control of the
+ resources it uses. In particular, it features explicit limits in the four
+ stacks and in the amount of live data. These limits are optional, can be
+ changed at run time, but they allow users to better control the
+ evolution of a program, handling memory and stack overflow gracefully via
+ the &CommonLisp; condition system.</para>
+
+ <para>The customizable limits are listed in <xref linkend="table.memory.limits" xrefstyle="select: label"/>, but they need a careful description.</para>
+ <itemizedlist>
+ <listitem><para><varname>ext:heap-size</varname> limits the total amount of
+ memory which is available for lisp objects. This is the memory used when
+ you create conses, arrays, structures, etc.</para></listitem>
+
+ <listitem><para><varname>ext:c-stack</varname> controls the size of the
+ stack for compiled code, including &ECL;'s library itself. This limit is
+ less stringent than the others. For instance, when code is compiled with
+ low safety settings, checks for this stack limit are usually omitted, for
+ performance reasons.</para></listitem>
+
+ <listitem><para><varname>ext:binding-stack</varname> controls the number of
+ nested bindings for special variables. The current value is usually safe
+ enough, unless you have deep recursive functions that bind special
+ variables, which is not really a good idea.</para></listitem>
+
+ <listitem><para><varname>ext:frame-stack</varname> controls the number of
+ nested blocks, tagbody and other control structures. It affects both
+ interpreted and compiled code, but quite often compiled code optimizes away
+ these stack frames, saving memory and not being affected by this
+ limit.</para></listitem>
+
+ <listitem><para><varname>ext:lisp-stack</varname> controls the size of the
+ interpreter stack. It only affects interpreted code.</para></listitem>
+ </itemizedlist>
+
+ <para>If you look at <xref linkend="table.memory.limits" xrefstyle="select: label"/>, some of these limits may seem very stringent, but they exist to allow detecting and correcting both stack and memory overflow conditions. Larger values can be set systematically either in the <filename>~/.eclrc</filename> initialization file, or using the command line options from the table.</para>
+
+ </section>
+
+ <section xml:id="ext.memory.conditions">
+ <title>Memory Conditions</title>
+
+ <para>When &ECL; surpasses or approaches the memory limits it will signal a &CommonLisp; condition. There are two types of conditions, <link linkend="ref.memory.stack-overflow"><symbol>ext:stack-overflow</symbol></link> and <link linkend="ref.memory.storage-exhausted"><symbol>ext:storage-exhausted</symbol></link>, for stack and heap overflows, respectively. Both errors are correctable, as the following session shows:</para>
+<programlisting>
+> (defun foo (x) (foo x))
+
+FOO
+> (foo 1)
+C-STACK overflow at size 1654784. Stack can probably be resized.
+Broken at SI:BYTECODES.Available restarts:
+1. (CONTINUE) Extend stack size
+Broken at FOO.
+>> :r1
+C-STACK overflow at size 2514944. Stack can probably be resized.
+Broken at SI:BYTECODES.Available restarts:
+1. (CONTINUE) Extend stack size
+Broken at FOO.
+>> :q
+Top level.
+</programlisting>
+ </section>
+
+ <section xml:id="ext.memory.finalization">
+ <title>Finalization</title>
+
+ <para>As we all know, Common-Lisp relies on garbage collection for deleting
+ unreachable objects. However, it makes no provision for the equivalent of a
+ C++ Destructor function that should be called when the object is eliminated
+ by the garbage collector. The equivalent of such methods in a garbage
+ collected environment is normally called a <emphasis>finalizer</emphasis>.</para>
+
+ <para>&ECL; includes a simple implementation of finalizers which makes the
+ following promises.</para>
+ <itemizedlist>
+
+ <listitem><para>The finalizer can be any lisp function, let it be compiled
+ or interpreter.</para></listitem>
+
+ <listitem><para>Finalizers are not invoked during garbage
+ collection. Instead, if an unreachable object is found to have an
+ associated finalizer, it is pushed into a list and <emphasis>before the
+ next garbage collection cycle</emphasis>, the finalizer will be
+ invoked. </para></listitem>
+
+ <listitem><para>If the finalizer is invoked and it makes the object
+ reachable, for instance, by assigning it to a variable, it will not be
+ destroyed, but it will have no longer a finalizer associated to
+ it.</para></listitem>
+
+ <listitem><para>&ECL; will strive to call finalizers before the environment
+ is closed and the program is finished, but this mechanism may fail when
+ exiting in a non ordinary way.</para></listitem>
+ </itemizedlist>
+
+ <para>The implementation is based on two functions, <link linkend="ref.memory.set-finalizer"><symbol>ext:set-finalizer</symbol></link> and <link linkend="ref.memory.get-finalizer"><symbol>ext:get-finalizer</symbol></link>, which allow setting and querying the finalizer functions for certain objects.</para>
+ </section>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ref_memory.xmlf" xpointer="ext.memory.dict"/>
+
+ </chapter>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <chapter xml:id="ext.mop">
+ <title>Meta-Object Protocol (MOP)</title>
+
+ <section xml:id="ext.mop.intro">
+ <title>Introduction</title>
+
+ <para>The Meta-Object Protocol is an extension to &CommonLisp; which
+ provides rules, functions and a type structure to handle the object
+ system. It is a reflective system, where classes are also objects and can be
+ created and manipulated using very well defined procedures.</para>
+
+ <para>The Meta-Object Protocol associated to &CommonLisp;'s object system
+ was introduced in a famous book, The Art of the Metaobject Protocol &AMOP;,
+ which was probably intended for the &ANSI; specification but was drop out
+ because of its revolutionary and then not too well tested ideas.</para>
+
+ <para>The &AMOP; is present, in one way or another, in most &CommonLisp;
+ implementations, eithr using proprietary systems or because their
+ implementation of &CLOS; descended from &PCL; (Portable CommonLoops). It has
+ thus become a de facto standard and &ECL; should not be without it.</para>
+
+ <para>Unfortunately &ECL;'s own implemention originally contained only a
+ subset of the &AMOP;. This was a clever decision at the time, since the
+ focus was on performance and on producing a stable and lean implementation
+ of &CommonLisp;. Nowadays it is however not an option, specially given that
+ most of the &AMOP; can be implemented with little cost for both the
+ implementor and the user.</para>
+
+ <para>So &ECL; has an almost complete implementation of the &AMOP;. However,
+ since it was written from scratch and progressed according to user's request
+ and our own innovations, there might still be some missing functionality
+ which we expect to correct in the near future. Please report any feature you
+ miss as a bug through the appropriate channels.</para>
+
+ <para>When considering the Metaobject Protocol, the book itself should be
+ the main reference. The following sections contain only further extensions
+ or improvements over the paragraphs which were either conflicting or less
+ specified.</para>
+ </section>
+
+ <section xml:id="ext.mop.classes">
+ <title>Classes</title>
+
+ <para>[TODO: Document the class initialization / finalization protocol]</para>
+ </section>
+
+ <section xml:id="ext.mop.slots">
+ <title>Slots</title>
+
+ <para>[TODO: Document the slot descriptions and parameters.]</para>
+
+ </section>
+
+ <section xml:id="ext.mop.generic">
+ <title>Generic functions and methods</title>
+
+ <para>[TODO: Document the calling convetions for method functions.]</para>
+ </section>
+
+ <section xml:id="ext.mop.slots.sealed">
+ <title>Sealed slots and classes</title>
+
+ <para>[TODO: Document sealed slots]</para>
+ </section>
+ </chapter>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <chapter xml:id="ext.mp">
+ <title>Multithreading</title>
+
+ <section xml:id="ext.mp.threads">
+ <title>Tasks, threads or processes</title>
+
+ <para>On most platforms, &ECL; supports native multithreading. That means
+ there can be several tasks executing lisp code on parallel and sharing
+ memory, variables and files. The interface for multitasting in &ECL;, like
+ those of most other implementations, is based on a set of functions and
+ types that resemble the multiprocessing capabilities of old Lisp Machines.
+ </para>
+
+ <para>This backward compatibility is why tasks or threads are called
+ "processes". However, they should not be confused with operating system
+ processes, which are made of programs running in separate contexts and
+ without access to each other's memory.</para>
+
+ <para>The implementation of threads in &ECL; is purely native and based on
+ Posix Threads wherever avaiable. The use of native threads has
+ advantanges. For instance, they allow for non-blocking file operations,
+ so that while one task is reading a file, a different one is performing
+ a computation.</para>
+
+ <para>As mentioned above, tasks share the same memory, as well as the set of
+ open files and sockets. This manifests on two features. First of all,
+ different tasks can operate on the same lisp objects, reading and writing
+ their slots, or manipulating the same arrays. Second, while threads share
+ global variables, constants and function definitions they can also have
+ thread-local bindings to special variables that are not seen by other
+ tasks.</para>
+
+ <para>The fact that different tasks have access to the same set of data
+ allows both for flexibility and a greater risk. In order to control access
+ to different resources, &ECL; provides the user with locks, as explained in
+ the next section.</para>
+
+ </section>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ref_mp.xmlf" xpointer="ext.mp.dict"/>
+
+ </chapter>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE chapter [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ext.os">
+ <title>Operating System Interface</title>
+
+ <section xml:id="ext.os.processes">
+ <title>Processes</title>
+
+ <para>&ECL; provides several facilities for invoking and communicating with
+ external processes. If one just wishes to execute some program, without
+ caring for its output, then probably <xref linkend="ref.system"/> is the best
+ function. In all other cases it is preferable to use <xref
+ linkend="ref.run-program"/>, which opens pipes to communicate with the
+ program and manipulate it while it runs on the background.</para>
+ </section>
+
+ <section xml:id="ext.os.command-line">
+ <title>Command line arguments</title>
+
+ <para></para>
+ </section>
+
+ <section xml:id="ext.os.dict">
+ <title>OS Reference</title>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ref_os.xmlf" xpointer="os.dict"/>
+
+ </section>
+</chapter>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+ -->
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="Program-development">
+ <title>Program Development Facilities</title>
+
+<section xml:id="The-stepper">
+<title>The Stepper</title>
+<blockquote>
+<screen><indexterm role="fn"><primary>step</primary></indexterm>— Macro: <function>step</function> <varname>form</varname></screen>
+<para>Starts evaluating the <replaceable>form</replaceable> in the single-step mode. In this mode, before
+any form is evaluated, the Stepper will print the form and prompt the user for
+a Stepper command. The Stepper binds the two variables print-level
+and print-length both to <literal>2</literal>, so that the current form may not
+occupy too much space on the screen. A Stepper command will be executed when
+the user types the single character for the command followed by the required
+arguments, if any, and presses the newline key. If the user presses the
+newline key without having typed any character, then the Stepper will assume
+that the Stepper command <literal>n</literal> was abbreviated.</para>
+</blockquote>
+<para>The stepper commands are:</para>
+<variablelist>
+<varlistentry>
+<term><literal>Newline</literal></term>
+<listitem>
+<para>Next. Evaluates the current form in the single-step mode.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><replaceable>:s</replaceable>, <replaceable>:skip</replaceable></term>
+<listitem>
+<para>Skip. Evaluates the current form in the ordinary mode. The single-step mode
+will be resumed at completion of the evaluation.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><replaceable>:b</replaceable>, <replaceable>:back</replaceable></term>
+<listitem>
+<para>Backwards. Steps back to previous step form.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><replaceable>:pr</replaceable>, <replaceable>:print</replaceable></term>
+<listitem>
+<para>Print. Pretty-prints the current form.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><replaceable>:form</replaceable></term>
+<listitem>
+<para>Form. Return the current form. Nothing is done, but the current form is
+returned as the value of this command. As a consequence, it is printed by the
+top level in the usual way and saved in the variable <literal>*</literal>. The main
+purpose of this command is to allow the current form to be examined further by
+accessing <literal>*</literal>.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><replaceable>:ret</replaceable>, <replaceable>:return</replaceable></term>
+<listitem>
+<para>Return. Return without evaluating the current form.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><replaceable>:x</replaceable>, <replaceable>:exit</replaceable></term>
+<listitem>
+<para>Exit. Evaluates the current form and any other forms in the ordinary mode.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>?</literal></term>
+<listitem>
+<para>Help. Lists the commands.</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</section>
+
+<section xml:id="Errors">
+<title>Errors</title>
+<blockquote>
+<screen><indexterm role="vr"><primary>*break-enable*</primary></indexterm>— Variable: <varname>*break-enable*</varname></screen>
+<para>This variable is used to determine whether to enter the break loop (see Section
+5.4) when an error occurs. Even the function <literal>break</literal> checks this
+variable. Initially, this variable is set to <replaceable>T</replaceable>, and thus an error will
+invoke the break loop. If the value is (), functions that cause fatal
+errors, such as <literal> error</literal>, will just print an error message and control
+will return to the top-level loop (or to the current break loop, if already in
+the break loop). Functions that cause correctable errors, such as <literal>
+cerror</literal>, will print an error message and a “continue message”, and control
+will return to the next form. In &ECL;, backtrace is not part of an error
+message, but a break loop command will print backtrace. Therefore, if
+break-enable is (), no backtrace appears on the screen.</para>
+<para>When the break loop is entered, break-enable will be bound to
+().</para>
+</blockquote>
+</section>
+
+<section xml:id="The-break-loop">
+<title>The Break Loop</title>
+<para>The break loop is a read-eval-print loop similar to the top-level loop. In
+addition to ordinary Lisp forms, the break loop accepts various commands with
+which the user can inspect and modify the state of the program execution. Each
+break loop command is identified with a keyword (i.e., a symbol in the
+<literal>keyword</literal> package). A break loop command is executed when the user inputs
+a list whose first element is the keyword that identifies the command. The
+rest of the list is the arguments to the command. They are evaluated before
+being passed to the command. If the command needs no arguments, then the user
+may input only the keyword. It is an error if the given keyword does not
+identify any command. Any other input to the break loop is regarded as an
+ordinary Lisp form; the form will be evaluated and the resulting values will be
+printed on the terminal.</para>
+<para>There can be several instances of the break loop at the same time, and each
+such instance is identified by a <emphasis>level number</emphasis>. When the break loop is
+entered during execution in the top-level loop, the break loop instance is
+given the level number 1. The break loop instance that is entered from the
+level <emphasis>n</emphasis> break loop is given the level number <replaceable>n</replaceable><literal>+1</literal>. The
+prompt of the level <emphasis>n</emphasis> break loop is <replaceable>n</replaceable><literal>+1</literal> consecutive
+<literal>></literal>'s, occasionally prefixed with the name of the current package.</para>
+<para>The break loop keeps track of the invocation sequence of functions (including
+special forms and macro expansion functions), which led up to the break loop
+from the previous break loop (or from the top-level loop, if the current break
+loop is level 1). The invocation sequence is maintained in a pushdown stack of
+<emphasis>events</emphasis>. An event consists of an <emphasis>event function</emphasis> and an
+<emphasis>event environment</emphasis>. An event function is:</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>an interpreted (i.e., not compiled) function (global function, local function, lambda-expression, or closure),</para>
+</listitem>
+<listitem>
+<para>a special form within an interpreted function,</para>
+</listitem>
+<listitem>
+<para>a macro expansion function called from an interpreted function,</para>
+</listitem>
+<listitem>
+<para>a compiled function called from an interpreted function, or</para>
+</listitem>
+<listitem>
+<para>a compiled function called from another compiled function which
+was compiled while the <literal>safety</literal> optimize level is 3 or with a
+<literal>notinline</literal> declaration for the called function (see Chapter 7).</para>
+</listitem>
+</orderedlist>
+<para>An event is pushed on the event stack when execution of its event function
+begins, and is popped away at the completion of the execution. An event
+environment is the `environment' of the event function at the time the next
+event is pushed. Actually, an event environment is a pointer to the main stack
+of &ECL;. For each interpreted event function (i.e., event function in
+classes 1, 2, and 3), the pointer points to the first entry of the three
+contiguous main stack entries that hold the lexical environment of the event
+function. For each compiled event function (i.e., event function in classes 4
+and 5), the pointer is set to the first entry of the main stack area that is
+used locally by the compiled code. In most cases, the first argument to the
+compiled function is saved in the first entry, the second argument in the
+second entry, and so on. The local variables of the function are allocated in
+the entries following the arguments. However, this is not always the case.
+Refer to Section 7.3 for variable allocations in compiled functions.</para>
+<para>By break level commands, the user can choose one of the events as the
+<emphasis>current event</emphasis>. If the current event function is an interpreted event
+function, then the break loop evaluates Lisp forms in the lexical environment
+retrieved from the event environment. In particular, local variables may be
+referenced by the variable names, local functions and local macros may be
+invoked as usual, established blocks may be exited from, and tags may be used
+as the destination of <literal>go</literal>. If the current function is a compiled
+function, Lisp forms are evaluated in the null environment.</para>
+<para>Within the break loop, each event is represented by the <emphasis>event symbol</emphasis>.
+The <replaceable>:backtrace</replaceable> command, for example, lists events in terms of their event
+symbols. If the event function is a named function (global or local) or a
+macro expansion function, then the function or macro name is used as the event
+symbol. If the event function is a special form, then the name of the special
+form is used. If the event function is a lambda-expression (or a closure),
+then the symbol lambda (or lambda-closure) is used.</para>
+<para>To suppress unnecessary information, the user can hide (or make invisible) some
+of the events. Invisible events do not appear in the backtrace, for example.
+Initially, only those events are invisible whose event symbols belong to the
+system internal package system. When the break loop is entered, the last
+visible event becomes the current event.</para>
+<para>The break loop commands are described below. Some of the commands allow
+abbreviation in the keywords that identify them. For example, the user may
+abbreviate <replaceable>:current</replaceable> as <replaceable>:c</replaceable>. The break loop commands return no values
+at all.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>:current</primary></indexterm>— Break Command: <function>:current</function></screen>
+<screen><indexterm role="fn"><primary>:c</primary></indexterm>— Break Command: <function>:c</function> <varname></varname></screen>
+<para>Prints the event symbol of the current event.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:previous</primary></indexterm>— Break Command: <function>:previous</function> <varname>&optional</varname> <varname>n</varname></screen>
+<screen><indexterm role="fn"><primary>:p</primary></indexterm>— Break Command: <function>:p</function> <varname>&optional n</varname></screen>
+<para>Makes the <replaceable>n</replaceable>-th previous visible event the
+new current event. Invisible events are not counted. If there are
+less than <replaceable>n</replaceable> previous events, then the first visible event in the
+invocation sequence becomes the new current event. <replaceable>n</replaceable> must be a
+positive integer and the default is <literal>1</literal>.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:next</primary></indexterm>— Break Command: <function>:next</function> <varname>&optional</varname> <varname>n</varname></screen>
+<screen><indexterm role="fn"><primary>:n</primary></indexterm>— Break Command: <function>:n</function> <varname>&optional n</varname></screen>
+<para>Makes the <replaceable>n</replaceable>-th next visible event the
+new current event. If there are less than <replaceable>n</replaceable> next events,
+then the last visible event in the invocation sequence
+becomes the new current event. <replaceable>n</replaceable> must be a positive integer and the
+default is <literal>1</literal>.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:backtrace</primary></indexterm>— Break Command: <function>:backtrace</function></screen>
+<screen><indexterm role="fn"><primary>:b</primary></indexterm>— Break Command: <function>:b</function> <varname></varname></screen>
+<para>Prints the event symbols of all visible events in order. The symbol of
+the current event is printed
+in upper-case letters and the event symbols of other events are in lower-case.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:help</primary></indexterm>— Break Command: <function>:help</function></screen>
+<screen><indexterm role="fn"><primary>:h</primary></indexterm>— Break Command: <function>:h</function> <varname></varname></screen>
+<para>Lists the break loop commands.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:quit</primary></indexterm>— Break Command: <function>:quit</function> <varname>&optional</varname> <varname>n</varname></screen>
+<screen><indexterm role="fn"><primary>:q</primary></indexterm>— Break Command: <function>:q</function> <varname>&optional n</varname></screen>
+<para>Returns control to the level <replaceable>n</replaceable> break loop. If <replaceable>n</replaceable> is 0 or if <replaceable>n</replaceable>
+is omitted, then control will return to the top-level loop. <replaceable>n</replaceable> must be a
+non-negative integer smaller than the current break level.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:continue</primary></indexterm>— Break Command: <function>:continue</function></screen>
+<screen><indexterm role="fn"><primary>:c</primary></indexterm>— Break Command: <function>:c</function> <varname></varname></screen>
+<para>Returns control to the caller of the break loop. If the break loop has been
+entered from <literal>cerror</literal>, <literal>cerror</literal> returns () as its value and
+control will resume at that point. Otherwise, this command returns control to
+the previous break loop (or to the top-level loop, if the current break level
+is <literal>1</literal>).</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:variables</primary></indexterm>— Break Command: <function>:variables</function></screen>
+<screen><indexterm role="fn"><primary>:v</primary></indexterm>— Break Command: <function>:v</function> <varname></varname></screen>
+<para>Prints the names of the bound variables in the current
+environment. To see the value of a bound variable, just type the
+variable name.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:functions</primary></indexterm>— Break Command: <function>:functions</function></screen>
+<para>Prints the names of the local functions and local macros in the current
+environment. To see the definition of a local function or macro, use the
+function special form in the usual way. That is, <literal>(function <replaceable>name</replaceable>)</literal>
+will return the definition of the local function or macro whose name is
+<replaceable>name</replaceable>. Local functions and local macros may be invoked as usual.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:blocks</primary></indexterm>— Break Command: <function>:blocks</function></screen>
+<para>Prints the names of the blocks established in the current environment. If a
+block <replaceable>block</replaceable> is established, then the <literal>return-from</literal> form
+<literal>(return-from <replaceable>block value</replaceable>)</literal> works as usual. That is, the block form
+that established <replaceable>block</replaceable> will return <replaceable>value</replaceable> as its value and control
+will resume at that point.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:tags</primary></indexterm>— Break Command: <function>:tags</function></screen>
+<para>Prints the tags established in the current environment. If a tag <replaceable>tag</replaceable> is
+established, then the <literal>go</literal> form <literal>(go <replaceable>tag</replaceable>)</literal> works as usual.
+That is, control will resume at the position of <replaceable>tag</replaceable> in the surrounding
+<literal>tagbody</literal>.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:local</primary></indexterm>— Break Command: <function>:local</function> <varname>&optional</varname> <varname>n</varname></screen>
+<screen><indexterm role="fn"><primary>:l</primary></indexterm>— Break Command: <function>:l</function> <varname>&optional n</varname></screen>
+<para>If <replaceable>n</replaceable> is <literal>0</literal> or if it is omitted, then this command prints the value
+stored in the main stack entry that is pointed to by the current event
+environment. <replaceable>n</replaceable> is an offset from that entry. If <replaceable>n</replaceable> is positive,
+then the value of the <emphasis>n</emphasis>-th next (i.e., toward the top of the main stack)
+entry is printed. If <replaceable>n</replaceable> is negative, then the value of the <replaceable>n</replaceable>-th
+previous (i.e., toward the bottom of the main stack) entry is printed. <replaceable>n</replaceable>
+must be an integer. It is an error if the specified entry does not lie between
+the bottom and the top of the stack.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:hide</primary></indexterm>— Break Command: <function>:hide</function> <varname>symbol</varname></screen>
+<para>Hides all events whose event symbol is <replaceable>symbol</replaceable>. In particular, by
+<literal>:hide 'lambda</literal> and <literal>hide 'lambda-closure</literal>, all events become
+invisible whose event functions are lambda-expressions and closures,
+respectively. If the event symbol of the current event happens to be
+<replaceable>symbol</replaceable>, then the last previous visible event will become the new current
+event. <replaceable>symbol</replaceable> must be a symbol.</para>
+<para>Events of <literal>eval</literal> and <literal>evalhook</literal> may never become invisible and
+attempts to hide them are simply ignored. It is always the case that the first
+event function is either <literal>eval</literal> or <literal>evalhook</literal>. Keeping both of them
+visible is the simplest way to avoid the silly attempts of the user to hide all
+events.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:hide-package</primary></indexterm>— Break Command: <function>:hide-package</function> <varname>package</varname></screen>
+<para>Hides all events whose event symbol belongs to the package
+<replaceable>package</replaceable>. <replaceable>package</replaceable> may be any object that represents a package, i.e.,
+a package object, a symbol, or a string. If the event symbol of the current
+event happens to belong to the package <replaceable>package</replaceable>, then the last previous
+visible event will become the new current event. Even if <literal>lisp</literal> package
+was specified as <replaceable>package</replaceable>, events of <literal>eval</literal> and <literal>evalhook</literal> do
+not become invisible. See the description of <replaceable>:hide</replaceable> above.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:unhide</primary></indexterm>— Break Command: <function>:unhide</function> <varname>symbol</varname></screen>
+<para><replaceable>:unhide</replaceable> is the inverse command of <replaceable>:hide</replaceable>. If, however, <replaceable> symbol</replaceable>
+belongs to one of the <replaceable>:hide-package</replaceable>d packages, events of <replaceable>symbol</replaceable>
+become visible only after the package is <literal>:unhide-package
+'d</literal>. <replaceable>symbol</replaceable> must be a symbol.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>:unhide-package</primary></indexterm>— Break Command: <function>:unhide-package</function> <varname>package</varname></screen>
+<para><replaceable>:unhide-package</replaceable> is the inverse command of <replaceable>:hide-package</replaceable>. However, an
+event whose event symbol belongs to <replaceable>package</replaceable> becomes visible only after
+the symbol is <literal>unhide 'd</literal>, if the symbol was <replaceable>:code 'd</replaceable>
+before. <replaceable>package</replaceable> may be any object that represents a package, i.e., a
+package object, a symbol, or a string.</para>
+</blockquote>
+<para>Example:</para>
+<para><screen>
+> (defun fact (x) (if (= x 0) one (* x (fact (1- x)))))
+fact ;;; Wrong definition for fact, the factorial.
+
+> (fact 6) ;;; Tries to calculate factorial 6.
+
+Error: The variable ONE is unbound.
+Error signalled by IF.
+
+Broken at IF: ;;; Enters the break-loop.
+>> :h ;;; Help.
+
+Break commands:
+:q(uit) Return to some previous break level.
+:pop Pop to previous break level.
+:c(ontinue) Continue execution.
+:b(acktrace) Print backtrace.
+:f(unction) Show current function.
+:p(revious) Go to previous function.
+:n(ext) Go to next function.
+:g(o) Go to next function.
+:fs Search forward for function.
+:bs Search backward for function.
+:v(ariables) Show local variables, functions, blocks, and tags.
+:l(ocal) Return the nth local value on the stack.
+:hide Hide function.
+:unhide Unhide function.
+:hp Hide package.
+:unhp Unhide package.
+:unhide-all Unhide all variables and packages.
+:vs Show value stack.
+:bds Show binding stack.
+:m(essage) Show error message.
+:hs Help stack.
+
+Top level commands:
+:cf Compile file.
+:exit or ^D Exit Lisp.
+:ld Load file.
+:step Single step form.
+:tr(ace) Trace function.
+:untr(ace) Untrace function.
+
+Help commands:
+:apropos Apropos.
+:doc(ument) Document.
+:h(elp) or ? Help. Type ":help help" for more information.
+
+>> :b ;;; Backtrace.
+Backtrace: eval > fact > if > fact > if > fact > if > fact >
+if > fact > if > fact > if > fact > IF
+
+>>: p ;;; Moves to the previous event.
+Broken at FACT.
+
+>> :b ;;; Now inside of fact but outside of if.
+Backtrace: eval > fact > if > fact > if > fact > if > fact >
+if > fact > if > fact > if > FACT > if
+
+>> :v ;;; Shows local variables.
+Local variables:
+X: 1
+Block names: FACT.
+
+>> x ;;; The value of x is 1.
+1
+
+>> (return-from fact 1) ;;; Returns from the fact block with value 1.
+720 ;;; Now the correct answer.
+
+> ;;; Top-level.
+</screen></para>
+</section>
+
+<section xml:id="Describe-and-inspect">
+<title>Describe and Inspect</title>
+<blockquote>
+<screen><indexterm role="fn"><primary>describe</primary></indexterm>— Function: <function>describe</function> <varname>object</varname></screen>
+<para>Prints the information about <replaceable>object</replaceable> to the stream that is the value of
+<literal>*standard-output*</literal>. The description of an object consists of several
+fields, each of which is described in a recursive manner. For example, a
+symbol may have fields such as home package, variable documentation, value,
+function documentation, function binding, type documentation, <literal>deftype</literal>
+definition, properties.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>inspect</primary></indexterm>— Function: <function>inspect</function> <varname>object</varname></screen>
+<para>Prints the information about <replaceable>object</replaceable> in an interactive manner. The output
+of inspect is similar to that of <literal>describe</literal>, but after printing the label
+and the value of a field (the value itself is not <literal>describe 'd</literal>), it
+prompts the user to input a one-character command. The input to <literal>inspect</literal>
+is taken from the stream that is the value of <literal>*query-io*</literal>. Normally, the
+inspection of <replaceable>object</replaceable> terminates after all of its fields have been
+inspected. The following commands are supported:</para>
+<variablelist>
+<varlistentry>
+<term><literal>n</literal></term>
+<listitem>
+<para>Next. Goes to the next level; the field is inspected recursively.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>s</literal></term>
+<listitem>
+<para>Skip. Skips the inspection of the field. <literal>inspect</literal> proceeds to the next
+field.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>p</literal></term>
+<listitem>
+<para>Print. Pretty-prints the field and prompts again.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>u</literal> <replaceable>form</replaceable></term>
+<listitem>
+<para>Update. The <replaceable>form</replaceable> is evaluated and the field is replaced by the resulting
+value. If the field cannot be updated, the message <literal>Not updated.</literal> will
+be printed.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>a</literal></term>
+<listitem>
+<para>Abort. Aborts the inspection of the current object. The field and
+the rest of the fields are not inspected.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>e</literal> <replaceable>form</replaceable></term>
+<listitem>
+<para>Eval. Evaluates the specified form in the null environment and prints the
+resulting values. Then prompts again with the same field.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>q</literal></term>
+<listitem>
+<para>Quit. Aborts the entire inspection.</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>?</literal></term>
+<listitem>
+<para>Help. Lists the <literal>inspect</literal> commands.</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</blockquote>
+</section>
+
+<section xml:id="The-profiler">
+<title>The Profiler</title>
+<para>The profiler tool is enabled by default in the basic &ECL; configuration. It
+can be disabled with the <literal>configure</literal> option <literal>--disable-profiler</literal>.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>profile</primary></indexterm>— sys: <function>profile</function> <varname>grain</varname> <varname>&optional</varname> <varname>address</varname></screen>
+<para>This function activates the profiling of subsequent executions. <replaceable>grain</replaceable> is
+a value between 1 and 16384 which indicates the granularity of code segments to
+consider. There is a counter for each such segment. With each clock tick, the
+current segment is identified and its corresponding histogram count is
+incremented. A value of 0 for <replaceable>grain</replaceable> means stop profiling. <replaceable>address</replaceable>
+indicates the base address for the code being profiled.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>display-profile</primary></indexterm>— sys: <function>display-profile</function></screen>
+<para>Displays the histogram of accumulated tick counts. The ticks are attributed to
+the compiled Lisp function whose base address is closest to the start of the
+segment. This may not be totally accurate for system functions which invoke
+some auxiliary function to do the job.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>clear-profile</primary></indexterm>— sys: <function>clear-profile</function></screen>
+<para>Clears the profile histogram.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="vr"><primary>sys</primary></indexterm>— Variable: <varname>sys</varname> <type>*profile-array*</type></screen>
+<para>Contains the profile histogram: two short integer counters are packed in each
+value of this array of fixnums.</para>
+</blockquote>
+</section>
+
+<section xml:id="Online-help">
+<title>Online Help</title>
+<para>Online help is provided by the following functions.</para>
+<blockquote>
+<screen><indexterm role="fn"><primary>help</primary></indexterm>— Function: <function>help</function> <varname>&optional symbol</varname></screen>
+<para><literal>help</literal> with no arguments prints a greeting message to &ECL; beginners.
+<literal>help</literal> with a symbol argument prints the documentation associated
+with the symbol.</para>
+</blockquote>
+<blockquote>
+<screen><indexterm role="fn"><primary>help*</primary></indexterm>— Function: <function>help*</function> <varname>string &optional package</varname></screen>
+<para>Prints the documentation associated with those symbols in the specified
+<replaceable>package</replaceable> whose print names contain <replaceable>string</replaceable> as substring.
+<replaceable>string</replaceable> may be a symbol, in which case the print name of that symbol is
+used. <replaceable>package</replaceable> is optional and defaults to the LISP package.
+If <replaceable>package</replaceable> is (), then all packages are searched.</para>
+</blockquote>
+</section>
+</chapter>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent:1
+ fill-column: 79
+ End:
+--></book>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE preface [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<preface xml:id="preface">
+ <title>Preface</title>
+
+ <section xml:id="preface.words">
+ <title>About this book</title>
+
+ <para>This manual is part of the &ECL; software system. It documents
+ deviations of &ECL; from various standards (&ANSI;, &AMOP;,...), extensions,
+ daily working process (compiling files, loading sources, creating programs,
+ etc) and the internals of this implementation.</para>
+
+ <para>This book is not intended as a source to learn &CommonLisp;. There are
+ other tutorials and textbooks available in the Net which serve this
+ purpose. The homepage of the <ulink url="http://www.lisp.org">Association of
+ Lisp Users</ulink> contains a good list of links of such teaching and
+ learning material.</para>
+
+ <para>This book is structured into three parts. We begin with <xref
+ linkend="part.standards"/> which documents all parts of the standard which
+ are left as <emphasis>implementation specific</emphasis>. For instance,
+ precision of floating point numbers, available character sets, actual
+ input/output protocols, etc.</para>
+
+ <para><xref linkend="part.extensions"/> introduces all features which are
+ specific to &ECL; and which lay outside the standard. This includes
+ configuring, building and installing &ECL; multiprocessing capabilities,
+ graphics libraries, interfacing with the operating system, etc.</para>
+
+ <para><xref linkend="part.internals"/> deals with the internals of the
+ implementation. This part is only intended for experienced programmers that
+ want to learn how &ECL; does its work and wish to extend it, customize it or
+ port it to new architectures. This part of the documentation is the most
+ fragile one and prone to change.</para>
+ </section>
+
+ <section xml:id="preface.what.is.ecl">
+ <title>What is &ECL;?</title>
+
+ <para>&CommonLisp; is a general purpose programming language. It lays its
+ roots in the <acronym>LISP</acronym> programming language <xref
+ linkend="bib.LISP1.5"/> developed by John McCarthy in the 80s. &CommonLisp;
+ as we know it &ANSI; is the result of an standarization process aimed at
+ unifying the multiple lisp dialects that were born from that language.</para>
+
+ <para>&ECL; is an implementation of the Common-Lisp language. As such it
+ derives from the implementation of the same name developed by Giuseppe
+ Attardi, which itself was built using code from the Kyoto Common-Lisp <xref
+ linkend="bib.KCL"/>. See <xref linkend="preface.history"></xref> for the
+ history of the code you are about to use.</para>
+
+ <para>&ECL; (ECL for short) uses standard C calling conventions for Lisp
+ compiled functions, which allows C programs to easily call Lisp functions
+ and vice versa. No foreign function interface is required: data can be
+ exchanged between C and Lisp with no need for conversion.</para>
+
+ <para>&ECL; is based on a Common Runtime Support (CRS) which provides basic
+ facilities for memory management, dynamic loading and dumping of binary
+ images, support for multiple threads of execution. The CRS is built into a
+ library that can be linked with the code of the application. &ECL; is
+ modular: main modules are the program development tools (top level,
+ debugger, trace, stepper), the compiler, and CLOS. A native implementation
+ of CLOS is available in &ECL;: one can configure &ECL; with or without CLOS.
+ A runtime version of &ECL; can be built with just the modules which are
+ required by the application.</para>
+
+ <para>The &ECL; compiler compiles from Lisp to C, and then invokes
+ the GNU C compiler to produce binaries. While former releases of ECL
+ adhere to the the reference of the language given in &Steele84;, the
+ aim of &ECL; is now to achieve maximum compliance with ANSI
+ Common-Lisp, the most up to date standard for Common-Lisp.</para>
+
+ </section>
+
+ <section xml:id="preface.history">
+ <title>History</title>
+
+ <para><figure float="1" xml:id="fig.family-tree">
+ <title>ECL's family tree</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata align="center" fileref="figures/hierarchy.png"
+ format="PNG" width="300px"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ The &ECL; project is an implementation of the Common-Lisp language inherits
+ from many other previous projects, as shown in <xref
+ linkend="fig.family-tree"/>. The oldest ancestor is the Kyoto Common Lisp, an
+ implementation developed at the the Research Institute for Mathematical
+ Sciences, Kyoto University <xref linkend="bib.KCL"/>. This
+ implementation was developed partially in C and partially in Common Lisp
+ itself and featured a lisp to C translator.</para>
+
+ <para>The <acronym>KCL</acronym> implementation remained a propietary project
+ for some time. During this time, William F. Schelter improved
+ <acronym>KCL</acronym> in several areas and developed Austin Kyoto
+ Common-Lisp (<acronym>AKCL</acronym>). However, those changes had to be
+ distributed as patches over the propietary <acronym>KCL</acronym>
+ implementation and it was not until much later that both
+ <acronym>KCL</acronym> and <acronym>AKCL</acronym> became freely available
+ and gave rise to the GNU Common Lisp project, <acronym>GCL</acronym>.</para>
+
+ <para>Around the 90's, Giusseppe Attardi worked on the <acronym>KCL</acronym>
+ and <acronym>AKCL</acronym> code basis to produce an implementation of
+ &CommonLisp; that could be embedded in other C programs <xref
+ linkend="bib.ECL"/>. The result was an implementation sometimes known as
+ <acronym>ECL</acronym> and sometimes as <acronym>ECoLisp</acronym>, which
+ achieved rather good compliance to the informal specification of the language
+ in &Steele84;, and which run on a rather big number of platforms.</para>
+
+ <para>The &ECL; project stagnated a little bit in the coming years. In
+ particular, certain dependencies such as object binary formats, word sizes
+ and some C quirks made it difficult to port it to new platforms. Furthermore,
+ &ECL; was not compliant with the <acronym>ANSI</acronym> specification, a
+ goal that other Common Lisps were struggling to achieve.</para>
+
+ <para>This is where the <acronym>ECLS</acronym> or
+ <acronym>ECL</acronym>-Spain project began. Juanjo García-Ripoll took
+ the ECoLisp sources and worked on them, with some immediate goals in mind:
+ increase portability, make the code 64-bit clean, make it able to build
+ itself from scratch, without other implementation of &CommonLisp; and restore
+ the ability to link &ECL; with other C programs.</para>
+
+ <para>Those goals were rather quickly achieved. &ECL; became ported to a
+ number of platforms and with the years also compatibility with the
+ <acronym>ANSI</acronym> specification became a more important goal. At some
+ point the fork <acronym>ECLS</acronym>, with agreement of Prof. Attardi, took
+ over the original <acronym>ECL</acronym> implementation and it became what it
+ is nowadays, a community project.</para>
+
+ <para>The &ECL; project owes a lot to different people who have contributed
+ in many different aspects, from pointing out bugs and incompatibilities of
+ &ECL; with other programs and specifications, to actually solving these bugs
+ and porting &ECL; to new platforms.</para>
+
+ <para>Currently, development of &ECL; is still driven by Juanjo
+ García-Ripoll with the help of Michael Goffioul in the Windows
+ port. The project homepage is located at <ulink
+ url="http://ecls.sourceforge.net"><uri>http://ecls.sourceforge.net</uri></ulink>,
+ and there is a mailing list where questions, bug reports and other
+ discussions may be carried out.</para>
+ </section>
+
+ <section xml:id="Copyright.ECL">
+ <title>Copyright of ECL</title>
+
+ <para>&ECL; is distributed under the GNU LGPL, which allows for commercial
+ uses of the software. A more precise description is given in the Copyright
+ notice which is shipped with &ECL;.</para>
+
+<programlisting>
+---- BEGINNING OF COPYRIGHT FOR THE ECL CORE ENVIRONMENT ------------
+
+ Copyright (c) 2000, Juan Jose Garcia Ripoll
+ Copyright (c) 1990, 1991, 1993 Giuseppe Attardi
+ Copyright (c) 1984 Taiichi Yuasa and Masami Hagiya
+ All Rights Reserved
+
+ ECL is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version; see file 'Copying'.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ PLEASE NOTE THAT:
+
+ This license covers all of the ECL program except for the files
+ src/lsp/loop2.lsp ; Symbolic's LOOP macro
+ src/lsp/pprint.lsp ; CMUCL's pretty printer
+ src/lsp/format.lsp ; CMUCL's format
+ and the directories
+ contrib/ ; User contributed extensions
+ src/clx/ ; portable CLX library from Telent
+ Look the precise copyright of these extensions in the corresponding
+ files.
+
+ Report bugs, comments, suggestions to the ecl mailing list:
+ ecls-list@lists.sourceforge.net.
+
+---- END OF COPYRIGHT FOR THE ECL CORE ENVIRONMENT ------------------</programlisting>
+ </section>
+
+ <section xml:id="Copyright.Manual">
+ <title>Copyright of this manual</title>
+
+ <para>Copyright: Juan José García-Ripoll, 2006.</para>
+
+ <para>Copyright: Kevin M. Rosenberg 2002-2003, (UFFI Reference)</para>
+
+ <itemizedlist>
+ <listitem><para>&ACL; is a registered trademark of Franz Inc.</para></listitem>
+ <listitem><para>&LW; is a registered trademark of Xanalys Inc.</para></listitem>
+ <listitem><para><productname>Microsoft Windows</productname> is a registered
+ trademark of Microsoft Inc.</para></listitem>
+ <listitem><para>Other brand or product names are the registered trademarks
+ or trademarks of their respective holders.</para></listitem>
+ </itemizedlist>
+
+ <para>Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1 or any
+ later version published by the Free Software Foundation; with no Invariant
+ Sections, with the no Front-Cover Texts, and with no Back-Cover Texts. A
+ copy of the license is shown below.</para>
+
+ <programlisting>
+ &GFDL;</programlisting>
+
+ </section>
+
+ <section xml:id="preface.installation">
+ <title>Installation</title>
+
+ <para>The following sections describe which machines are supported by &ECL;,
+ how to build and install it on them. You should read at least <xref
+ linkend="preface.platforms"/> and in particular <xref linkend="table.ports"/>
+ which details the other sections containing installation instructions for
+ your platform.</para>
+
+ <section xml:id="preface.platforms">
+ <title>Supported platforms</title>
+
+ <table xml:id="table.ports">
+ <title>Supported platforms</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Architecture</entry>
+ <entry>Operating system</entry>
+ <entry>Toolchain</entry>
+ <entry>Tested<footnote><para>YES means that a dedicated machine regularly builds and tests &ECL; on this platform.</para></footnote></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>x86 <footnote xml:id="note.x86"><para>Intel 32 bit processors
+ (Pentium, Pentium II, Pentium 3, Pentium 4) and AMD
+ clones</para></footnote>
+ </entry>
+ <entry>Linux</entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>x86_64<footnote xml:id="note.amd"><para>AMD and Intel processors with
+ 64 bit extensions.</para></footnote></entry>
+ <entry>Linux</entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>PPC</entry>
+ <entry>Linux</entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>Itanium</entry>
+ <entry>Linux</entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>x86</entry>
+ <entry>FreeBSD</entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>x86</entry>
+ <entry><link linkend="preface.bsd">OpenBSD</link></entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>x86</entry>
+ <entry><link linkend="preface.bsd">NetBSD</link></entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>x86</entry>
+ <entry>Windows XP, Vista, 7</entry>
+ <entry><link linkend="preface.msvc">Microsoft compilers</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>x86</entry>
+ <entry>Windows XP, Vista, 7</entry>
+ <entry><link linkend="preface.autoconf">&cygwin;</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>x86</entry>
+ <entry>Windows XP, Vista, 7</entry>
+ <entry><link linkend="preface.autoconf">&mingw; and Msys tools</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>x86</entry>
+ <entry>OS X Tiger</entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>x86_64</entry>
+ <entry>OS X Tiger</entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>x86</entry>
+ <entry>Solaris</entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>x86_64</entry>
+ <entry>Solaris</entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ <row>
+ <entry>Sparc</entry>
+ <entry>Solaris</entry>
+ <entry><link linkend="preface.autoconf">Autoconf</link></entry>
+ <entry>YES</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>In <xref linkend="table.ports"/> we show the operating systems in
+ which ECL is known to run and where it is regularly tested. Note that ECL
+ might successfully build on other platforms, and that porting is relatively
+ easy. We regularly get reports on ECL being built on other platforms (ARM,
+ Motorola 68x, Sparc, etc), so the best thing is to try yourself.</para>
+
+ </section>
+
+ <section xml:id="preface.autoconf">
+ <title>Autoconf based configuration</title>
+
+ <para>&ECL;, like many other free programs, can be built and installed a GNU
+ tool called Autoconf. This is a set of automatically generated scripts that
+ detect the features of your machine, such as the compiler type, existing
+ libraries, desired installation path, and configures &ECL; accordingly. The
+ following procedure describes how to build &ECL; using this procedure and it
+ applies to all platforms except for the Windows ports.</para>
+
+ <procedure>
+ <step>
+ <para>Unpack the tar file</para>
+ <screen>$ gunzip -c ecl-0.9i.tgz | tar xf -</screen>
+ </step>
+ <step><para>Choose a directory in which you will install &ECL;. Following
+ the Unix covention we will use
+ <filename>/usr/local</filename></para></step>
+ <step>
+ <para>Run the configuration file
+ <screen>$ cd ecl-0.9i
+ $ ./configure --prefix=/usr/local</screen>
+ If you are building under Solaris 9 you should replace the last line with
+ <screen>$ ./configure --enable-slow-config --with-system-gmp=no \
+ --prefix=/usr/local</screen>
+ By now you should have a directory with the name
+ <filename>build</filename> and a bunch of makefiles inside it.</para>
+ </step>
+ <step>
+ <para>Use GNU make to begin building ECL. Normally this amounts to
+ invoking
+ <screen>$ make</screen>
+ from the command line.</para>
+ </step>
+ <step>
+ <para>Install the program using
+ <screen>$ make install</screen>
+ </para>
+ </step>
+ <step>
+ <para>Make sure the program is installed and ready to run
+ <screen>$ /usr/local/ecl
+ ECL (Embeddable Common-Lisp) 0.9i
+ Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
+ Copyright (C) 1993 Giuseppe Attardi
+ Copyright (C) 2000 Juan J. Garcia-Ripoll
+ ECL is free software, and you are welcome to redistribute it
+ under certain conditions; see file 'Copyright' for details.
+ Type :h for Help. Broken at EVAL.
+ > </screen>
+ </para>
+ </step>
+ </procedure>
+
+ </section>
+
+ <section xml:id="preface.osdep">
+ <title>Platform specific instructions</title>
+
+ <section xml:id="preface.msvc">
+ <title>Microsoft compilers</title>
+
+ <para>If you have a commercial version of Microsoft Visual Studio, the
+ steps are simple:</para>
+ <procedure>
+ <step><para>Change to the <code>msvc</code> directory.</para></step>
+
+ <step><para>Run <code>nmake</code> to build ECL.</para></step>
+
+ <step><para>Run <code>nmake install prefix=d:\Software\ECL</code>
+ where the <code>prefix</code> is the directory where you want to install
+ ECL.</para></step>
+
+ <step><para>Optionally, if you want to build a self-installing
+ executable, you can install <ulink
+ url="http://nsis.sourceforge.net">NSIS</ulink> and run <code>nmake
+ windows-nsi</code>.</para></step>
+ </procedure>
+
+ <para>If you want to build ECL using the free Microsoft Visual Studio
+ Express 2010 or better, you should follow these before building ECL as
+ sketched before:</para>
+ <procedure>
+ <step><para>Download and install <ulink
+ url="http://www.microsoft.com/express/">Microsoft Visual Studio
+ C++ Compiler</ulink>.</para></step>
+
+ <step><para>Download and install the <ulink
+ url="http://msdn.microsoft.com/en-us/windows/bb980924">Windows
+ SDK</ulink></para></step>
+
+ <step><para>Open the Windows SDK terminal, which will set up the
+ appropriate paths and environment variables.</para>
+ </step>
+ </procedure>
+ </section>
+
+ <section xml:id="preface.bsd">
+ <title>OpenBSD and NetBSD</title>
+
+ <para>Before following the instructions in <xref linkend="preface.autoconf"/> you should install the following packages: <application>boehm-gc</application> and <application>gmp-4.1</application> or better. Another component, <application>libffi</application> will be needed if you want to use the <link linkend="ext.ffi">dynamic foreign interface</link>.</para>
+ </section>
+
+ </section>
+ </section>
+</preface>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent:1
+ fill-column: 79
+ End:
+ -->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Arrays</title>
+<section xml:id="ansi.arrays.c-dict">
+<title>C Reference</title>
+ <refentry xml:id="ansi.arrays.c-types">
+ <refnamediv>
+ <refname>Types and constants</refname>
+ <refpurpose>C types, limits and enumerations</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Constants and types</title>
+
+ <synopsis><constant>ECL_ARRAY_RANK_LIMIT</constant></synopsis>
+
+ <synopsis><constant>ECL_ARRAY_DIMENSION_LIMIT</constant></synopsis>
+
+ <synopsis><constant>ECL_ARRAY_TOTAL_LIMIT</constant></synopsis>
+
+ <synopsis><type>typedef enum { ecl_aet_object, ...} cl_elttype;</type></synopsis>
+
+ <simplelist columns="4" type="horiz" xml:id="cl_elttype">
+ <member>Lisp or C type</member>
+ <member>Enumeration value</member>
+
+ <member>Lisp or C type</member>
+ <member>Enumeration value</member>
+
+ <member><type>t</type></member>
+ <member><type>ecl_aet_object</type></member>
+
+ <member><type>(unsigned-byte 1)</type></member>
+ <member><type>ecl_aet_bit</type></member>
+
+ <member><type>cl_fixnum</type></member>
+ <member><type>ecl_aet_fix</type></member>
+
+ <member><type>cl_index</type></member>
+ <member><type>ecl_aet_index</type></member>
+
+ <member><type>(unsigned-byte 8)</type></member>
+ <member><type>ecl_aet_b8</type></member>
+
+ <member><type>(signed-byte 8)</type></member>
+ <member><type>ecl_aet_i8</type></member>
+
+ <member><type>(unsigned-byte 16)</type></member>
+ <member><type>ecl_aet_b16</type></member>
+
+ <member><type>(signed-byte 16)</type></member>
+ <member><type>ecl_aet_i16</type></member>
+
+ <member><type>(unsigned-byte 32)</type></member>
+ <member><type>ecl_aet_b32</type></member>
+
+ <member><type>(signed-byte 32)</type></member>
+ <member><type>ecl_aet_i32</type></member>
+
+ <member><type>(unsigned-byte 64)</type></member>
+ <member><type>ecl_aet_b64</type></member>
+
+ <member><type>(signed-byte 64)</type></member>
+ <member><type>ecl_aet_i64</type></member>
+
+ <member><type>ecl_character</type></member>
+ <member><type>ecl_aet_ch</type></member>
+
+ <member><type>ecl_base_char</type></member>
+ <member><type>ecl_aet_bc</type></member>
+
+ <member><type>single-float</type></member>
+ <member><type>ecl_aet_sf</type></member>
+
+ <member><type>double-float</type></member>
+ <member><type>ecl_aet_df</type></member>
+ </simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This list contains the constants that limit the rank of an array (<constant>ECL_ARRAY_RANK_LIMIT</constant>), the maximum size of each dimension (<constant>ECL_ARRAY_DIMENSION_LIMIT</constant>) and the maximum number of elements in an array (<constant>ECL_ARRAY_TOTAL_LIMIT</constant>).</para>
+
+ <para>&ECL; uses also internally a set of constants to describe the different specialized arrays. The constants form up the enumeration type <type>cl_elttype</type>. They are listed in the table above, which associates enumeration values with the corresponding Common Lisp element type.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname><function>ecl_aet_to_symbol</function>,
+ <function>ecl_symbol_to_aet</function></refname>
+ <refpurpose>To and from element types</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Functions</title>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_aet_to_symbol</function></funcdef>
+ <paramdef>cl_elttype <parameter>param</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_elttype <function>ecl_symbol_to_aet</function></funcdef>
+ <paramdef>cl_object <parameter>type</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ecl_aet_to_symbol</function> returns the Lisp type associated to the elements of that specialized array class. <function>ecl_symbol_to_aet</function> does the converse, computing the C constant that is associated to a Lisp elment type.</para>
+
+ <para>The functions may signal an error if any of the arguments is an invalid C or Lisp type.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>Constructors</refname>
+ <refpurpose>Creating arrays and vectors</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Functions</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_alloc_simple_vector</function></funcdef>
+ <paramdef>cl_elttype <parameter>element_type</parameter></paramdef>
+ <paramdef>cl_index <parameter>length</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>si_make_vector</function></funcdef>
+ <paramdef>cl_object <parameter>element_type</parameter></paramdef>
+ <paramdef>cl_object <parameter>length</parameter></paramdef>
+ <paramdef>cl_object <parameter>adjustablep</parameter></paramdef>
+ <paramdef>cl_object <parameter>fill_pointerp</parameter></paramdef>
+ <paramdef>cl_object <parameter>displaced_to</parameter></paramdef>
+ <paramdef>cl_object <parameter>displacement</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>si_make_array</function></funcdef>
+ <paramdef>cl_object <parameter>element_type</parameter></paramdef>
+ <paramdef>cl_object <parameter>dimensions</parameter></paramdef>
+ <paramdef>cl_object <parameter>adjustablep</parameter></paramdef>
+ <paramdef>cl_object <parameter>fill_pointerp</parameter></paramdef>
+ <paramdef>cl_object <parameter>displaced_to</parameter></paramdef>
+ <paramdef>cl_object <parameter>displacement</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The function <function>ecl_alloc_simple_vector</function> is the simplest constructor, creating a simple vector (i.e. non-adjustable and without a fill pointer), of the given size, preallocating the memory for the array data. The first argument, <replaceable>element_type</replaceable>, is a C constant that represents a valid array element type (See <link linkend="cl_elttype">cl_elttype</link>).</para>
+
+ <para>The function <function>si_make_vector</function> does the same job but allows creating an array with fill pointer, which is adjustable or displaced to another array.</para>
+ <itemizedlist>
+ <listitem><para><replaceable>element_type</replaceable> is now a Common Lisp type descriptor, which is a symbol or list denoting a valid element type</para></listitem>
+ <listitem><para><replaceable>dimension</replaceable> is a non-negative fixnum with the vector size.</para></listitem>
+ <listitem><para><replaceable>fill_pointerp</replaceable> is either <symbol>Cnil</symbol> or a non-negative fixnum denoting the fill pointer value.</para></listitem>
+ <listitem><para><replaceable>displaced_to</replaceable> is either <symbol>Cnil</symbol> or a valid array to which the new array is displaced.</para></listitem>
+ <listitem><para><replaceable>displacement</replaceable> is either <symbol>Cnil</symbol> or a non-negative value with the array displacement.</para></listitem>
+ </itemizedlist>
+ <para>Finally, the function <function>si_make_array</function> does a similar job to <function>si_make_function</function> but its second argument, <replaceable>dimension</replaceable>, can be a list of dimensions, to create a multidimensional array.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>Create one-dimensional <type>base-string</type> with room for 11 characters:</para>
+<programlisting>
+cl_object s = ecl_alloc_simple_vector(ecl_aet_bc, 11);
+</programlisting>
+
+ <para>Create a one-dimensional <type>array</type> with a fill pointer</para>
+<programlisting>
+cl_object type = ecl_make_symbol("BYTE8","EXT");
+cl_object a = si_make_vector(ecl_make_fixnum(16), type, Cnil, /* adjustable */
+ ecl_make_fixnum(0) /* fill-pointer */,
+ Cnil /* displaced_to */,
+ Cnil /* displacement */);
+</programlisting>
+
+ <para>An alternative formulation</para>
+<programlisting>
+cl_object type = ecl_make_symbol("BYTE8","EXT");
+cl_object a = si_make_array(ecl_make_fixnum(16), type, Cnil, /* adjustable */
+ ecl_make_fixnum(0) /* fill-pointer */,
+ Cnil /* displaced_to */,
+ Cnil /* displacement */);
+</programlisting>
+
+ <para>Create a 2-by-3 two-dimensional <type>array</type>, specialized for an integer type:</para>
+<programlisting>
+cl_object dims = cl_list(2, ecl_make_fixnum(2), ecl_make_fixnum(3));
+cl_object type = ecl_make_symbol("BYTE8","EXT");
+cl_object a = si_make_array(dims, type, Cnil, /* adjustable */
+ Cnil /* fill-pointer */,
+ Cnil /* displaced_to */,
+ Cnil /* displacement */);
+</programlisting>
+ </refsect1>
+
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>Accessors</refname>
+ <refpurpose>Reading and writing array elements</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Functions</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_aref</function></funcdef>
+ <paramdef>cl_object <parameter>array</parameter></paramdef>
+ <paramdef>cl_index <parameter>row_major_index</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_aset</function></funcdef>
+ <paramdef>cl_object <parameter>array</parameter></paramdef>
+ <paramdef>cl_index <parameter>row_major_index</parameter></paramdef>
+ <paramdef>cl_object <parameter>new_value</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_aref1</function></funcdef>
+ <paramdef>cl_object <parameter>vector</parameter></paramdef>
+ <paramdef>cl_index <parameter>row_major_index</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_aset1</function></funcdef>
+ <paramdef>cl_object <parameter>vector</parameter></paramdef>
+ <paramdef>cl_index <parameter>row_major_index</parameter></paramdef>
+ <paramdef>cl_object <parameter>new_value</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ecl_aref</function> accesses an array using the supplied <replaceable>row_major_index</replaceable>, checking the array bounds and returning a Lisp object for the value at that position. <function>ecl_aset</function> does the converse, storing a Lisp value at the given <replaceable>row_major_index</replaceable>.</para>
+
+ <para>The first argument to <function>ecl_aref</function> or <function>ecl_aset</function> is an array of any number of dimensions. For an array of rank <replaceable>N</replaceable> and dimensions <replaceable>d1</replaceable>, <replaceable>d2</replaceable> ... up to <replaceable>dN</replaceable>, the row major index associated to the indices <replaceable>(i1,i2,...iN)</replaceable> is computed using the formula <code>i1+d1*(i2+d3*(i3+...))</code>.</para>
+
+ <para><function>ecl_aref1</function> and <function>ecl_aset1</function> are specialized versions that only work with one-dimensional arrays or vectors. They verify that the first argument is indeed a vector.</para>
+
+ <para>All functions above check that the index does not exceed the array bounds, that the values match the array element type and that the argument is an array (or a vector). If these conditions are not met, a type error is signaled.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>Array properties</refname>
+ <refpurpose>Array size, fill pointer, etc</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_elttype <function>ecl_array_elttype</function></funcdef>
+ <paramdef>cl_object <parameter>array</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_index <function>ecl_array_rank</function></funcdef>
+ <paramdef>cl_object <parameter>array</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_index <function>ecl_array_dimension</function></funcdef>
+ <paramdef>cl_object <parameter>array</parameter></paramdef>
+ <paramdef>cl_index <parameter>index</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>These functions query various properties of the arrays. Some of them belong to the list of functions in the Common Lisp package, without any need for specialized versions. More precisely</para>
+ <itemizedlist>
+ <listitem><para><function>ecl_array_elttype</function> returns the array element type, with the encoding found in the enumeration <link linkend="cl_elttype">cl_elttype</link>.</para></listitem>
+ <listitem><para><function>ecl_array_rank</function> returns the number of dimensions of the vector or array.</para></listitem>
+ <listitem><para><function>ecl_array_dimension</function> queries the dimension of an array, where <replaceable>index</replaceable> is a non-negative integer between 0 and <code>ecl_array_dimension(array)-1</code>.</para></listitem>
+ </itemizedlist>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_mk_ar.htm"><symbol>make-array</symbol></ulink></member>
+<member><code>cl_object cl_make_array(cl_narg narg, cl_object dimension...)</code></member>
+
+<member><ulink url="&clhs;f_adjust.htm"><symbol>adjust-array</symbol></ulink></member>
+<member><code>cl_object cl_adjust_array(cl_narg narg, cl_object array, cl_object dimensions, ...)</code></member>
+
+<member><ulink url="&clhs;f_adju_1.htm"><symbol>adjustable-array-p</symbol></ulink></member>
+<member><code>cl_object cl_adjustable_array_p(cl_object array)</code></member>
+
+<member><ulink url="&clhs;f_aref.htm"><symbol>aref</symbol></ulink></member>
+<member><code>cl_object cl_aref(cl_narg narg, cl_object array, ...)</code></member>
+
+<member><ulink url="&clhs;f_ar_dim.htm"><symbol>array-dimension</symbol></ulink></member>
+<member><code>cl_object cl_array_dimension(cl_object array, cl_object index)</code></member>
+
+<member><ulink url="&clhs;f_ar_d_1.htm"><symbol>array-dimensions</symbol></ulink></member>
+<member><code>cl_object cl_array_dimension(cl_object array)</code></member>
+
+<member><ulink url="&clhs;f_ar_ele.htm"><symbol>array-element-type</symbol></ulink></member>
+<member><code>cl_object cl_array_element_type(cl_object array)</code></member>
+
+<member><ulink url="&clhs;f_ar_has.htm"><symbol>array-has-fill-pointer-p</symbol></ulink></member>
+<member><code>cl_object cl_array_has_fill_pointer_p(cl_object array)</code></member>
+
+<member><ulink url="&clhs;f_ar_dis.htm"><symbol>array-displacement</symbol></ulink></member>
+<member><code>cl_object cl_array_displacement(cl_object array)</code></member>
+
+<member><ulink url="&clhs;f_ar_in_.htm"><symbol>array-in-bounds-p</symbol></ulink></member>
+<member><code>cl_object cl_array_in_bounds_p(cl_narg narg, cl_object array, ...)</code></member>
+
+<member><ulink url="&clhs;f_ar_ran.htm"><symbol>array-rank</symbol></ulink></member>
+<member><code>cl_object cl_array_rank(cl_object array)</code></member>
+
+<member><ulink url="&clhs;f_ar_row.htm"><symbol>array-row-major-index</symbol></ulink></member>
+<member><code>cl_object cl_array_row_major_index(cl_narg narg, cl_object array, ...)</code></member>
+
+<member><ulink url="&clhs;f_ar_tot.htm"><symbol>array-total-size</symbol></ulink></member>
+<member><code>cl_object cl_array_total_size(cl_object array)</code></member>
+
+<member><ulink url="&clhs;f_arrayp.htm"><symbol>arrayp</symbol></ulink></member>
+<member><code>cl_object cl_arrayp(cl_object array)</code></member>
+
+<member><ulink url="&clhs;f_fill_p.htm"><symbol>fill-pointer</symbol></ulink></member>
+<member><code>cl_object cl_fill_pointer(cl_object array)</code></member>
+
+<member><ulink url="&clhs;f_row_ma.htm"><symbol>row-major-aref</symbol></ulink></member>
+<member><code>cl_object cl_row_major_aref(cl_object array, cl_object index)</code></member>
+
+<member><ulink url="&clhs;f_upgr_1.htm"><symbol>upgraded-array-element-type</symbol></ulink></member>
+<member><code>cl_object cl_upgraded_array_element_type(cl_narg narg, cl_object typespec, ...) </code></member>
+
+<member><ulink url="&clhs;f_smp_ve.htm"><symbol>simple-vector-p</symbol></ulink></member>
+<member><code>cl_object cl_simple_vector_p(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_svref.htm"><symbol>svref</symbol></ulink></member>
+<member><code>cl_object cl_svref(cl_object simple_vector, cl_object index)</code></member>
+
+<member><ulink url="&clhs;f_vector.htm"><symbol>vector</symbol></ulink></member>
+<member><code>cl_object cl_vector(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_vec_po.htm"><symbol>vector-pop</symbol></ulink></member>
+<member><code>cl_object cl_vector_pop(cl_object vector)</code></member>
+
+<member><ulink url="&clhs;f_vec_ps.htm"><symbol>vector-push</symbol></ulink></member>
+<member><code>cl_object cl_vector_push(cl_object new_element, cl_object vector)</code></member>
+
+<member><ulink url="&clhs;f_vec_ps.htm"><symbol>vector-push-extend</symbol></ulink></member>
+<member><code>cl_object cl_vector_push_extend(cl_narg narg, cl_object new_element, cl_object vector, ...)</code></member>
+
+<member><ulink url="&clhs;f_vecp.htm"><symbol>vectorp</symbol></ulink></member>
+<member><code>cl_object cl_vectorp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_bt_sb.htm"><symbol>bit</symbol></ulink></member>
+<member><code>cl_object cl_bit(cl_narg narg, cl_object bit_array, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_sb.htm"><symbol>sbit</symbol></ulink></member>
+<member><code>cl_object cl_sbit(cl_narg narg, cl_object bit_array, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_and.htm"><symbol>bit-and</symbol></ulink></member>
+<member><code>cl_object cl_bit_and(cl_narg narg, cl_object array1, cl_object array2, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_and.htm"><symbol>bit-andc1</symbol></ulink></member>
+<member><code>cl_object cl_bit_andc1(cl_narg narg, cl_object array1, cl_object array2, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_and.htm"><symbol>bit-andc2</symbol></ulink></member>
+<member><code>cl_object cl_bit_andc2(cl_narg narg, cl_object array1, cl_object array2, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_and.htm"><symbol>bit-eqv</symbol></ulink></member>
+<member><code>cl_object cl_bit_eqv(cl_narg narg, cl_object array1, cl_object array2, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_and.htm"><symbol>bit-ior</symbol></ulink></member>
+<member><code>cl_object cl_bit_ior(cl_narg narg, cl_object array1, cl_object array2, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_and.htm"><symbol>bit-nand</symbol></ulink></member>
+<member><code>cl_object cl_bit_nand(cl_narg narg, cl_object array1, cl_object array2, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_and.htm"><symbol>bit-nor</symbol></ulink></member>
+<member><code>cl_object cl_bit_nor(cl_narg narg, cl_object array1, cl_object array2, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_and.htm"><symbol>bit-orc1</symbol></ulink></member>
+<member><code>cl_object cl_bit_orc1(cl_narg narg, cl_object array1, cl_object array2, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_and.htm"><symbol>bit-orc2</symbol></ulink></member>
+<member><code>cl_object cl_bit_orc1(cl_narg narg, cl_object array1, cl_object array2, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_and.htm"><symbol>bit-xor</symbol></ulink></member>
+<member><code>cl_object cl_bit_xor(cl_narg narg, cl_object array1, cl_object array2, ...)</code></member>
+
+<member><ulink url="&clhs;f_bt_and.htm"><symbol>bit-not</symbol></ulink></member>
+<member><code>cl_object cl_bit_not(cl_narg narg, cl_object array, ...)</code></member>
+
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Characters</title>
+<section xml:id="ansi.characters.c-dict">
+<title>C Reference</title>
+ <refentry xml:id="ansi.characters.c-types">
+ <refnamediv>
+ <refname>C types</refname>
+ <refpurpose>C character types</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Type names</title>
+ <simplelist columns="2" type="horiz">
+ <member><type>ecl_character</type></member>
+ <member><type>character</type></member>
+
+ <member><type>ecl_base_char</type></member>
+ <member><type>base-char</type></member>
+ </simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>&ECL; defines two C types to hold its characters: <type>ecl_base_char</type> and <type>ecl_character</type>.</para>
+ <itemizedlist>
+ <listitem><para>When &ECL; is built without Unicode, they both coincide and typically match <type>unsigned char</type>, to cover the 256 codes that are needed.</para></listitem>
+ <listitem><para>When &ECL; is built with Unicode, the two types are no longer equivalent, with <type>ecl_character</type> being larger.</para></listitem>
+ </itemizedlist>
+
+ <para>For your code to be portable and future proof, use both types to really express what you intend to do.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>Constructors</refname>
+ <refpurpose>Creating and extracting characters from Lisp objects</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Functions and macros</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ECL_CODE_CHAR</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>code</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>ecl_character <function>ECL_CHAR_CODE</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>o</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_char_code</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>code</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>ecl_base_char <function>ecl_base_char_code</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>o</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>These functions and macros convert back and forth from C character types to Lisp. The macros <function>ECL_CHAR_CODE</function> and <function>ECL_CODE_CHAR</function> perform this coercion without checking the arguments. The functions <function>ecl_char_code</function> and <function>ecl_base_char_code</function>, on the other hand, verify that the argument has the right type and signal an error otherwise.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>Predicates</refname>
+ <refpurpose>C predicates for Lisp characters</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Functions and macros</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>bool <function>ecl_base_char_p</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>bool <function>ecl_alpha_char_p</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>bool <function>ecl_alphanumeric_p</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>bool <function>ecl_graphic_char_p</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>bool <function>ecl_digit_p</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>bool <function>ecl_standard_char_p</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>These functions are equivalent to their Lisp equivalents but return C booleans.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>Character case</refname>
+ <refpurpose>C functions related to the character case</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Functions and macros</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>bool <function>ecl_upper_case_p</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>bool <function>ecl_lower_case_p</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>bool <function>ecl_both_case_p</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>ecl_character <function>ecl_char_downcase</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>ecl_character <function>ecl_char_upcase</function></funcdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>These functions check or change the case of a character. Note that in an Unicode context, the output of these functions might not be accurate (for instance when the uppercase character has two or more codepoints).</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char=</symbol></ulink></member>
+<member><code>cl_object cl_charE(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char/=</symbol></ulink></member>
+<member><code>cl_object cl_charNE(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char<</symbol></ulink></member>
+<member><code>cl_object cl_charL(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char></symbol></ulink></member>
+<member><code>cl_object cl_charG(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char<=</symbol></ulink></member>
+<member><code>cl_object cl_charLE(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char>=</symbol></ulink></member>
+<member><code>cl_object cl_charGE(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char-equal</symbol></ulink></member>
+<member><code>cl_object cl_char_equal(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char-not-equal</symbol></ulink></member>
+<member><code>cl_object cl_char_not_equal(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char-lessp</symbol></ulink></member>
+<member><code>cl_object cl_char_lessp(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char-greaterp</symbol></ulink></member>
+<member><code>cl_object cl_char_greaterp(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char-not-greaterp</symbol></ulink></member>
+<member><code>cl_object cl_char_not_greaterp(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_chareq.htm"><symbol>char-not-lessp</symbol></ulink></member>
+<member><code>cl_object cl_char_not_lessp(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_ch.htm"><symbol>character</symbol></ulink></member>
+<member><code>cl_object cl_character(cl_object char_designator)</code></member>
+
+<member><ulink url="&clhs;f_chp.htm"><symbol>characterp</symbol></ulink></member>
+<member><code>cl_object cl_characterp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_alpha_.htm"><symbol>alpha-char-p</symbol></ulink></member>
+<member><code>cl_object cl_alpha_char_p(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_alphan.htm"><symbol>alphanumericp</symbol></ulink></member>
+<member><code>cl_object cl_alphanumericp(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_digit_.htm"><symbol>digit-char</symbol></ulink></member>
+<member><code>cl_object cl_digit_char(cl_narg narg, cl_object character, ...)</code></member>
+
+<member><ulink url="&clhs;f_digi_1.htm"><symbol>digit-char-p</symbol></ulink></member>
+<member><code>cl_object cl_digit_char_p(cl_narg narg, cl_object character, ...)</code></member>
+
+<member><ulink url="&clhs;f_graphi.htm"><symbol>graphic-char-p</symbol></ulink></member>
+<member><code>cl_object cl_graphic_char_p(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_std_ch.htm"><symbol>standard-char-p</symbol></ulink></member>
+<member><code>cl_object cl_standard_char_p(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_char_u.htm"><symbol>char_upcase</symbol></ulink></member>
+<member><code>cl_object cl_char_upcase(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_char_u.htm"><symbol>char-downcase</symbol></ulink></member>
+<member><code>cl_object cl_char_downcase(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_upper_.htm"><symbol>upper-case-p</symbol></ulink></member>
+<member><code>cl_object cl_upper_case_p(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_upper_.htm"><symbol>lower-case-p</symbol></ulink></member>
+<member><code>cl_object cl_lower_case_p(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_upper_.htm"><symbol>both-case-p</symbol></ulink></member>
+<member><code>cl_object cl_both_case_p(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_char_c.htm"><symbol>char-code</symbol></ulink></member>
+<member><code>cl_object cl_char_code(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_char_i.htm"><symbol>char-int</symbol></ulink></member>
+<member><code>cl_object cl_char_int(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_code_c.htm"><symbol>code-char</symbol></ulink></member>
+<member><code>cl_object cl_code_char(cl_object code)</code></member>
+
+<member><ulink url="&clhs;f_char_n.htm"><symbol>char-name</symbol></ulink></member>
+<member><code>cl_object cl_char_name(cl_object character)</code></member>
+
+<member><ulink url="&clhs;f_name_c.htm"><symbol>name-char</symbol></ulink></member>
+<member><code>cl_object cl_name_char(cl_object name)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Conditions</title>
+<section xml:id="ansi.conditions.c-dict">
+<title>C Reference</title>
+ <refentry xml:id="ECL_HANDLER_CASE">
+ <refnamediv>
+ <refname><function>ECL_HANDLER_CASE</function></refname>
+ <refpurpose>C macro for <ulink url="&clhs;m_hand_1.htm"><symbol>handler-case</symbol></ulink></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <synopsis><code><function>ECL_HANDLER_CASE_BEGIN</function>(env,names) {</code></synopsis>
+ <synopsis><code>} <function>ECL_HANDLER_CASE(n,condition) {</function> {</code></synopsis>
+ <synopsis><code>} <function>ECL_HANDLER_CASE_END</function>;</code></synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ECL_HANDLER_CASE_BEGIN</function> runs a block of C code with a set of error handlers bound to the names given by the list <replaceable>names</replaceable>. The subsequent <function>ECL_HANDLER_CASE</function> statements specify what to do when the <replaceable>n</replaceable>-th type of conditions is found, where <replaceable>n</replaceable> is an integer denoting the position of the name in the list <replaceable>names</replaceable>.</para>
+
+ <para>When a condition is signaled, &ECL; scans the list of signal handlers, looking for matches based on <symbol>typep</symbol>. If the match with the highest precedence belongs to the list <replaceable>names</replaceable>, &ECL; will perform a non-local transfer of control to the appropriate <function>ECL_HANDLER_CASE</function>, passing it a <replaceable>condition</replaceable> object as unique argument.</para>
+
+ <para>The following example shows how to establish a handler for <symbol>ERROR</symbol> conditions. Note how the first value to <function>ECL_HANDLER_CASE</function> matches the position of the restart name in the list:</para>
+ <programlisting>
+cl_object error = ecl_make_symbol("ERROR","CL");
+ECL_RESTART_BEGIN(the_env, ecl_list1(error)) {
+ /* This form is evaluated with bound handlers */
+ output = cl_eval(1, form);
+} ECL_HANDLER_CASE(1, condition) {
+ /* This code is executed when an error happens */
+ /* We just return the error that took place */
+ output = condition;
+} ECL_RESTART_END;
+ </programlisting>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="ECL_RESTART_CASE">
+ <refnamediv>
+ <refname><function>ECL_RESTART_CASE</function></refname>
+ <refpurpose>C macro for <ulink url="&clhs;m_rst_ca.htm"><symbol>restart-case</symbol></ulink></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <synopsis><code><function>ECL_RESTART_CASE_BEGIN</function>(env,names) {</code></synopsis>
+ <synopsis><code>} <function>ECL_RESTART_CASE(n,args) {</function> {</code></synopsis>
+ <synopsis><code>} <function>ECL_RESTART_CASE_END</function>;</code></synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ECL_RESTART_CASE_BEGIN</function> runs a block of C code with a set of restarts bound to the names given by the list <replaceable>names</replaceable>. The subsequent <function>ECL_RESTART_CASE</function> statements specify what to do when the <replaceable>n</replaceable>-th restart is invoked, where <replaceable>n</replaceable> is an integer denoting the position of the name in the list <replaceable>names</replaceable>.</para>
+
+ <para>When the restart is invoked, it can receive any number of arguments, which are grouped in a list and stored in a new variable created with the name <replaceable>args</replaceable>.</para>
+
+ <para>The following example shows how to establish an <symbol>ABORT</symbol> and a <symbol>USE-VALUE</symbol> restart. Note how the first value to <function>ECL_RESTART_CASE</function> matches the position of the restart name in the list:</para>
+ <programlisting>
+cl_object abort = ecl_make_symbol("ABORT","CL");
+cl_object use_value = ecl_make_symbol("USE-VALUE","CL");
+ECL_RESTART_BEGIN(the_env, cl_list(2, abort, use_value)) {
+ /* This form is evaluated with bound restarts */
+ output = cl_eval(1, form);
+} ECL_RESTART_CASE(1, args) {
+ /* This code is executed when the 1st restart (ABORT) is invoked */
+ output = Cnil;
+} ECL_RESTART_CASE(2, args) {
+ /* This code is executed when the 2nd restart (ABORT) is invoked */
+ output = ECL_CAR(args);
+} ECL_RESTART_END;
+ </programlisting>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>Conditions C dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_abortc.htm"><symbol>abort</symbol></ulink></member>
+<member><code>cl_object cl_abort(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_break.htm"><symbol>break</symbol></ulink></member>
+<member><code>cl_object cl_break()</code></member>
+
+<member><ulink url="&clhs;f_cell_e.htm"><symbol>cell-error-name</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_cerror.htm"><symbol>cerror</symbol></ulink></member>
+<member><code>cl_object cl_cerror(cl_narg narg, cl_object continue_format_control, cl_object datum, ...)</code></member>
+
+<member><ulink url="&clhs;f_comp_1.htm"><symbol>compute-restarts</symbol></ulink></member>
+<member><code>cl_object cl_compute_restarts(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_abortc.htm"><symbol>continue</symbol></ulink></member>
+<member><code>cl_object cl_continue(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_error.htm"><symbol>error</symbol></ulink></member>
+<member><code>cl_object cl_error(cl_narg narg, cl_object datum, ...)</code></member>
+
+<member><ulink url="&clhs;f_find_r.htm"><symbol>find-restart</symbol></ulink></member>
+<member><code>cl_object cl_find_restart(cl_narg narg, cl_object identifier, ...)</code></member>
+
+<member><ulink url="&clhs;m_hand_1.htm"><symbol>handler-case</symbol></ulink></member>
+<member><link linkend="ECL_HANDLER_CASE"><function>ECL_HANDLER_CASE</function></link> macro</member>
+
+<member><ulink url="&clhs;f_invali.htm"><symbol>invalid-method-error</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_invoke.htm"><symbol>invoke-debugger</symbol></ulink></member>
+<member><code>cl_object cl_invoke_debugger(cl_object condition)</code></member>
+
+<member><ulink url="&clhs;f_invo_1.htm"><symbol>invoke-restart</symbol></ulink></member>
+<member><code>cl_object cl_invoke_restart(cl_narg narg, cl_object restart, ...)</code></member>
+
+<member><ulink url="&clhs;f_invo_2.htm"><symbol>invoke-restart-interactively</symbol></ulink></member>
+<member><code>cl_object cl_invoke_restart_interactively(cl_object restart)</code></member>
+
+<member><ulink url="&clhs;f_mk_cnd.htm"><symbol>make-condition</symbol></ulink></member>
+<member><code>cl_object cl_make_condition(cl_narg narg, cl_object type)</code></member>
+
+<member><ulink url="&clhs;f_meth_1.htm"><symbol>method-combination-error</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_abortc.htm"><symbol>muffle-warning</symbol></ulink></member>
+<member><code>cl_object cl_muffle_warning(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_rst_na.htm"><symbol>restart-name</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;m_rst_ca.htm"><symbol>restart-case</symbol></ulink></member>
+<member><link linkend="ECL_RESTART_CASE"><function>ECL_RESTART_CASE</function></link> macro</member>
+
+<member><ulink url="&clhs;f_signal.htm"><symbol>signal</symbol></ulink></member>
+<member><code>cl_object cl_signal(cl_narg narg, cl_object datum, ...)</code></member>
+
+<member><ulink url="&clhs;f_smp_cn.htm"><symbol>simple-condition-format-control</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_smp_cn.htm"><symbol>simple-condition-format-arguments</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_abortc.htm"><symbol>store-value</symbol></ulink></member>
+<member><code>cl_object cl_store_value(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_abortc.htm"><symbol>use-value</symbol></ulink></member>
+<member><code>cl_object cl_use_value(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_warn.htm"><symbol>warn</symbol></ulink></member>
+<member><code>cl_object cl_warn(cl_narg narg, cl_object datum, ...)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Conses</title>
+<section xml:id="ansi.conses.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_cons.htm"><symbol>cons</symbol></ulink></member>
+<member><code>cl_object cl_cons(cl_object car, cl_object cdr)</code></member>
+
+<member><ulink url="&clhs;f_consp.htm"><symbol>consp</symbol></ulink></member>
+<member><code>cl_object cl_consp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_atom.htm"><symbol>atom</symbol></ulink></member>
+<member><code>cl_object cl_atom(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_rplaca.htm"><symbol>rplaca</symbol></ulink></member>
+<member><code>cl_object cl_rplaca(cl_object cons, cl_object car)</code></member>
+
+<member><ulink url="&clhs;f_rplaca.htm"><symbol>rplacd</symbol></ulink></member>
+<member><code>cl_object cl_rplacd(cl_object cons, cl_object cdr)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>car</symbol></ulink></member>
+<member><code>cl_object cl_car(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cdr</symbol></ulink></member>
+<member><code>cl_object cl_cdr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>caar</symbol></ulink></member>
+<member><code>cl_object cl_caar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cdar</symbol></ulink></member>
+<member><code>cl_object cl_cdar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cadr</symbol></ulink></member>
+<member><code>cl_object cl_cadr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cddr</symbol></ulink></member>
+<member><code>cl_object cl_cddr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>caaar</symbol></ulink></member>
+<member><code>cl_object cl_caaar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cdaar</symbol></ulink></member>
+<member><code>cl_object cl_cdaar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cadar</symbol></ulink></member>
+<member><code>cl_object cl_cadar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cddar</symbol></ulink></member>
+<member><code>cl_object cl_cddar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>caadr</symbol></ulink></member>
+<member><code>cl_object cl_caadr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cdadr</symbol></ulink></member>
+<member><code>cl_object cl_cdadr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>caddr</symbol></ulink></member>
+<member><code>cl_object cl_caddr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cdddr</symbol></ulink></member>
+<member><code>cl_object cl_cdddr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>caaaar</symbol></ulink></member>
+<member><code>cl_object cl_caaaar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cdaaar</symbol></ulink></member>
+<member><code>cl_object cl_cdaaar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cadaar</symbol></ulink></member>
+<member><code>cl_object cl_cadaar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cddaar</symbol></ulink></member>
+<member><code>cl_object cl_cddaar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>caadar</symbol></ulink></member>
+<member><code>cl_object cl_caadar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cdadar</symbol></ulink></member>
+<member><code>cl_object cl_cdadar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>caddar</symbol></ulink></member>
+<member><code>cl_object cl_caddar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cdddar</symbol></ulink></member>
+<member><code>cl_object cl_cdddar(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>caaadr</symbol></ulink></member>
+<member><code>cl_object cl_caaadr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cdaadr</symbol></ulink></member>
+<member><code>cl_object cl_cdaadr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cadadr</symbol></ulink></member>
+<member><code>cl_object cl_cadadr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cddadr</symbol></ulink></member>
+<member><code>cl_object cl_cddadr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>caaddr</symbol></ulink></member>
+<member><code>cl_object cl_caaddr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cdaddr</symbol></ulink></member>
+<member><code>cl_object cl_cdaddr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cadddr</symbol></ulink></member>
+<member><code>cl_object cl_cadddr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_car_c.htm"><symbol>cddddr</symbol></ulink></member>
+<member><code>cl_object cl_cddddr(cl_object cons)</code></member>
+
+<member><ulink url="&clhs;f_cp_tre.htm"><symbol>copy-tree</symbol></ulink></member>
+<member><code>cl_object cl_copy_tree(cl_object tree)</code></member>
+
+<member><ulink url="&clhs;f_sublis.htm"><symbol>sublis</symbol></ulink></member>
+<member><code>cl_object cl_sublis(cl_narg narg, cl_object alist, cl_object tree, ...)</code></member>
+
+<member><ulink url="&clhs;f_nsublis.htm"><symbol>nsublis</symbol></ulink></member>
+<member><code>cl_object cl_sublis(cl_narg narg, cl_object alist, cl_object tree, ...)</code></member>
+
+<member><ulink url="&clhs;f_substc.htm"><symbol>subst</symbol></ulink></member>
+<member><code>cl_object cl_subst(cl_narg narg, cl_object new, cl_object old, cl_object tree, ...)</code></member>
+
+<member><ulink url="&clhs;f_substc.htm"><symbol>subst-if</symbol></ulink></member>
+<member><code>cl_object cl_subst_if(cl_narg narg, cl_object new, cl_object predicate, cl_object tree, ...)</code></member>
+
+<member><ulink url="&clhs;f_substc.htm"><symbol>subst-if-not</symbol></ulink></member>
+<member><code>cl_object cl_subst_if_not(cl_narg narg, cl_object new, cl_object predicate, cl_object tree, ...)</code></member>
+
+<member><ulink url="&clhs;f_substc.htm"><symbol>nsubst</symbol></ulink></member>
+<member><code>cl_object cl_nsubst(cl_narg narg, cl_object new, cl_object old, cl_object tree, ...)</code></member>
+
+<member><ulink url="&clhs;f_substc.htm"><symbol>nsubst-if</symbol></ulink></member>
+<member><code>cl_object cl_nsubst_if(cl_narg narg, cl_object new, cl_object predicate, cl_object tree, ...)</code></member>
+
+<member><ulink url="&clhs;f_substc.htm"><symbol>nsubst-if-not</symbol></ulink></member>
+<member><code>cl_object cl_nsubst_if_not(cl_narg narg, cl_object new, cl_object predicate, cl_object tree, ...)</code></member>
+
+<member><ulink url="&clhs;f_tree_e.htm"><symbol>tree-equal</symbol></ulink></member>
+<member><code>cl_object cl_tree_equal(cl_narg narg, cl_object tree1, cl_object tree2, ...)</code></member>
+
+<member><ulink url="&clhs;f_cp_lis.htm"><symbol>copy-list</symbol></ulink></member>
+<member><code>cl_object cl_copy_list(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_list_.htm"><symbol>list</symbol></ulink></member>
+<member><code>cl_object cl_list(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_list_.htm"><symbol>list*</symbol></ulink></member>
+<member><code>cl_object cl_listA(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_list_l.htm"><symbol>list-length</symbol></ulink></member>
+<member><code>cl_object cl_list_length(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_listp.htm"><symbol>listp</symbol></ulink></member>
+<member><code>cl_object cl_listp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_mk_lis.htm"><symbol>make-list</symbol></ulink></member>
+<member><code>cl_object cl_make_list(cl_narg narg, cl_object size, ...)</code></member>
+
+<member><ulink url="&clhs;f_firstc.htm"><symbol>first</symbol></ulink></member>
+<member><code>cl_object cl_first(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_firstc.htm"><symbol>second</symbol></ulink></member>
+<member><code>cl_object cl_second(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_firstc.htm"><symbol>third</symbol></ulink></member>
+<member><code>cl_object cl_third(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_firstc.htm"><symbol>fourth</symbol></ulink></member>
+<member><code>cl_object cl_fourth(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_firstc.htm"><symbol>fifth</symbol></ulink></member>
+<member><code>cl_object cl_fifth(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_firstc.htm"><symbol>sixth</symbol></ulink></member>
+<member><code>cl_object cl_sixth(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_firstc.htm"><symbol>seventh</symbol></ulink></member>
+<member><code>cl_object cl_seventh(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_firstc.htm"><symbol>eighth</symbol></ulink></member>
+<member><code>cl_object cl_eighth(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_firstc.htm"><symbol>ninth</symbol></ulink></member>
+<member><code>cl_object cl_ninth(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_firstc.htm"><symbol>tenth</symbol></ulink></member>
+<member><code>cl_object cl_tenth(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_nth.htm"><symbol>nth</symbol></ulink></member>
+<member><code>cl_object cl_nth(cl_object n, cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_endp.htm"><symbol>endp</symbol></ulink></member>
+<member><code>cl_object cl_endp(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_null.htm"><symbol>null</symbol></ulink></member>
+<member><code>cl_object cl_null(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_nconc.htm"><symbol>nconc</symbol></ulink></member>
+<member><code>cl_object cl_nconc(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_append.htm"><symbol>append</symbol></ulink></member>
+<member><code>cl_object cl_append(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_revapp.htm"><symbol>revappend</symbol></ulink></member>
+<member><code>cl_object cl_revappend(cl_object list, cl_object tail)</code></member>
+
+<member><ulink url="&clhs;f_revapp.htm"><symbol>nreconc</symbol></ulink></member>
+<member><code>cl_object cl_nreconc(cl_object list, cl_object tail)</code></member>
+
+<member><ulink url="&clhs;f_butlas.htm"><symbol>butlast</symbol></ulink></member>
+<member><code>cl_object cl_butlast(cl_narg narg, cl_object list, ...)</code></member>
+
+<member><ulink url="&clhs;f_butlas.htm"><symbol>nbutlast</symbol></ulink></member>
+<member><code>cl_object cl_nbutlast(cl_narg narg, cl_object list, ...)</code></member>
+
+<member><ulink url="&clhs;f_last.htm"><symbol>last</symbol></ulink></member>
+<member><code>cl_object cl_last(cl_narg narg, cl_object list, ...)</code></member>
+
+<member><ulink url="&clhs;f_ldiffc.htm"><symbol>ldiff</symbol></ulink></member>
+<member><code>cl_object cl_ldiff(cl_object list, cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_ldiffc.htm"><symbol>tailp</symbol></ulink></member>
+<member><code>cl_object cl_tailp(cl_object object, cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_nthcdr.htm"><symbol>nthcdr</symbol></ulink></member>
+<member><code>cl_object cl_nthcdr(cl_object n, cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_rest.htm"><symbol>rest</symbol></ulink></member>
+<member><code>cl_object cl_rest(cl_object list)</code></member>
+
+<member><ulink url="&clhs;f_mem_m.htm"><symbol>member</symbol></ulink></member>
+<member><code>cl_object cl_member(cl_narg narg, cl_object member, cl_object list, ....)</code></member>
+
+<member><ulink url="&clhs;f_mem_m.htm"><symbol>member-if</symbol></ulink></member>
+<member><code>cl_object cl_member_if(cl_narg narg, cl_object predicate, cl_object list, ....)</code></member>
+
+<member><ulink url="&clhs;f_mem_m.htm"><symbol>member-if-not</symbol></ulink></member>
+<member><code>cl_object cl_member_if_not(cl_narg narg, cl_object predicate, cl_object list, ....)</code></member>
+
+<member><ulink url="&clhs;f_mapc_.htm"><symbol>mapc</symbol></ulink></member>
+<member><code>cl_object cl_mapc(cl_narg narg, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;f_mapc_.htm"><symbol>mapcar</symbol></ulink></member>
+<member><code>cl_object cl_mapcar(cl_narg narg, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;f_mapc_.htm"><symbol>mapcan</symbol></ulink></member>
+<member><code>cl_object cl_mapcan(cl_narg narg, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;f_mapc_.htm"><symbol>mapl</symbol></ulink></member>
+<member><code>cl_object cl_mapl(cl_narg narg, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;f_mapc_.htm"><symbol>maplist</symbol></ulink></member>
+<member><code>cl_object cl_maplist(cl_narg narg, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;f_mapc_.htm"><symbol>mapcon</symbol></ulink></member>
+<member><code>cl_object cl_mapcon(cl_narg narg, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;f_acons.htm"><symbol>acons</symbol></ulink></member>
+<member><code>cl_object cl_acons(cl_object key, cl_object datum, cl_object alist)</code></member>
+
+<member><ulink url="&clhs;f_assocc.htm"><symbol>assoc</symbol></ulink></member>
+<member><code>cl_object cl_assoc(cl_narg narg, cl_object item, cl_object alist, ...)</code></member>
+
+<member><ulink url="&clhs;f_assocc.htm"><symbol>assoc-if</symbol></ulink></member>
+<member><code>cl_object cl_assoc_if(cl_narg narg, cl_object predicate, cl_object alist, ...)</code></member>
+
+<member><ulink url="&clhs;f_assocc.htm"><symbol>assoc-if-not</symbol></ulink></member>
+<member><code>cl_object cl_assoc_if_not(cl_narg narg, cl_object predicate, cl_object alist, ...)</code></member>
+
+<member><ulink url="&clhs;f_cp_ali.htm"><symbol>copy-alist</symbol></ulink></member>
+<member><code>cl_object cl_copy_alist(cl_object alist)</code></member>
+
+<member><ulink url="&clhs;f_pairli.htm"><symbol>pairlis</symbol></ulink></member>
+<member><code>cl_object cl_pairlis(cl_narg narg, cl_object keys, cl_object data, ...)</code></member>
+
+<member><ulink url="&clhs;f_rassoc.htm"><symbol>rassoc</symbol></ulink></member>
+<member><code>cl_object cl_rassoc(cl_narg narg, cl_object item, cl_object alist, ...)</code></member>
+
+<member><ulink url="&clhs;f_rassoc.htm"><symbol>rassoc-if</symbol></ulink></member>
+<member><code>cl_object cl_rassoc_if(cl_narg narg, cl_object predicate, cl_object alist, ...)</code></member>
+
+<member><ulink url="&clhs;f_rassoc.htm"><symbol>rassoc-if-not</symbol></ulink></member>
+<member><code>cl_object cl_rassoc_if_not(cl_narg narg, cl_object predicate, cl_object alist, ...)</code></member>
+
+<member><ulink url="&clhs;f_get_pr.htm"><symbol>get-properties</symbol></ulink></member>
+<member><code>cl_object cl_get_properties(cl_object plist, cl_object indicator_list)</code></member>
+
+<member><ulink url="&clhs;f_getf.htm"><symbol>getf</symbol></ulink></member>
+<member><code>cl_object cl_getf(cl_narg narg, cl_object plist, cl_object indicator, ...)</code></member>
+
+<member><ulink url="&clhs;f_isec_.htm"><symbol>intersection</symbol></ulink></member>
+<member><code>cl_object cl_intersection(cl_narg narg, cl_object list1, cl_object list2, ...)</code></member>
+
+<member><ulink url="&clhs;f_isec_.htm"><symbol>nintersection</symbol></ulink></member>
+<member><code>cl_object cl_nintersection(cl_narg narg, cl_object list1, cl_object list2, ...)</code></member>
+
+<member><ulink url="&clhs;f_adjoin.htm"><symbol>adjoin</symbol></ulink></member>
+<member><code>cl_object cl_adjoin(cl_narg narg, cl_object item, cl_object list, ...)</code></member>
+
+<member><ulink url="&clhs;f_set_di.htm"><symbol>set-difference</symbol></ulink></member>
+<member><code>cl_object cl_set_difference(cl_narg narg, cl_object list1, cl_object list2, ...)</code></member>
+
+<member><ulink url="&clhs;f_set_di.htm"><symbol>nset-difference</symbol></ulink></member>
+<member><code>cl_object cl_nset_difference(cl_narg narg, cl_object list1, cl_object list2, ...)</code></member>
+
+<member><ulink url="&clhs;f_set_ex.htm"><symbol>set-exclusive-or</symbol></ulink></member>
+<member><code>cl_object cl_set_exclusive_or(cl_narg narg, cl_object list1, cl_object list2, ...)</code></member>
+
+<member><ulink url="&clhs;f_set_ex.htm"><symbol>nset-exclusive-or</symbol></ulink></member>
+<member><code>cl_object cl_nset_exclusive_or(cl_narg narg, cl_object list1, cl_object list2, ...)</code></member>
+
+<member><ulink url="&clhs;f_subset.htm"><symbol>subsetp</symbol></ulink></member>
+<member><code>cl_object cl_subsetp(cl_narg narg, cl_object list1, cl_object list2, ...)</code></member>
+
+<member><ulink url="&clhs;f_unionc.htm"><symbol>union</symbol></ulink></member>
+<member><code>cl_object cl_union(cl_narg narg, cl_object list1, cl_object list2)</code></member>
+
+<member><ulink url="&clhs;f_unionc.htm"><symbol>nunion</symbol></ulink></member>
+<member><code>cl_object cl_nunion(cl_narg narg, cl_object list1, cl_object list2)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Data and control flow</title>
+<section xml:id="ansi.data-and-control.c-dict">
+ <title>C Reference</title>
+
+ <refentry xml:id="ecl_bds_bind">
+ <refnamediv>
+ <refname><function>ecl_bds_bind</function></refname>
+ <refpurpose>Bind a special variable</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Functions</title>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef><function>ecl_bds_bind</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>cl_env</parameter></paramdef>
+ <paramdef>cl_object <parameter>var</parameter></paramdef>
+ <paramdef>cl_object <parameter>value</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef><function>ecl_bds_push</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>cl_env</parameter></paramdef>
+ <paramdef>cl_object <parameter>var</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Establishes a variable binding for the symbol <replaceable>var</replaceable> in the Common Lisp environment <replaceable>env</replaceable>, assigning it <replaceable>value</replaceable>.</para>
+
+ <para>This macro or function is the equivalent of <ulink url="&clhs;s_let_l.htm"><symbol>LET*</symbol></ulink> and <ulink url="&clhs;s_let_l.htm"><symbol>LET</symbol></ulink>.</para>
+
+ <para><function>ecl_bds_push</function> does a similar thing, but reuses the old value of the same variable. It is thus the equivalent of <code>(LET ((VAR VAR)) ...)</code></para>
+
+ <para>Every variable binding must undone when no longer needed. It is best practice to match each call to <function>ecl_bds_bind</function> by another call to <link linkend="ecl_bds_unwind"><function>ecl_bds_unwind</function></link> in the same function.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="ecl_bds_unwind">
+ <refnamediv>
+ <refname><function>ecl_bds_unwind</function></refname>
+ <refpurpose>Undo one variable binding</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef><function>ecl_bds_unwind1</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>cl_env</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef><function>ecl_bds_unwind_n</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>cl_env</parameter></paramdef>
+ <paramdef>int <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ecl_bds_unwind1</function> undoes the outermost variable binding, restoring the original value of the symbol in the process.</para>
+
+ <para><function>ecl_bds_unwind_n</function> does the same, but for the <replaceable>n</replaceable> last variables.</para>
+
+ <para>Every variable binding must undone when no longer needed. It is best practice to match each call to <function>ecl_bds_bind</function> by another call to <link linkend="ecl_bds_unwind"><function>ecl_bds_unwind</function></link> in the same function.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="ecl_setq">
+ <refnamediv>
+ <refname><function>ecl_setq</function></refname>
+ <refpurpose>C equivalent of <ulink url="&clhs;s_setq.htm"><symbol>setq</symbol></ulink></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef><function>ecl_setq</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>cl_env</parameter></paramdef>
+ <paramdef>cl_object <parameter>var</parameter></paramdef>
+ <paramdef>cl_object <parameter>value</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Assigns <replaceable>value</replaceable> to the special variable denoted by the symbol <replaceable>var</replaceable>, in the Common Lisp environment <replaceable>cl_env</replaceable>.</para>
+
+ <para>This function implements a variable assignment, not a variable binding. It is thus the equivalent of <ulink url="&clhs;s_setq.htm"><symbol>setq</symbol></ulink>.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="ecl_symbol_value">
+ <refnamediv>
+ <refname><function>ecl_symbol_value</function></refname>
+ <refpurpose>C equivalent of <ulink url="&clhs;f_symb_5.htm"><symbol>symbol-value</symbol></ulink></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Funciton</title>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef><function>ecl_symbol_value</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>cl_env</parameter></paramdef>
+ <paramdef>cl_object <parameter>var</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Retrieves the value of the special variable or constant denoted by the symbol <replaceable>var</replaceable>, in the Common Lisp environment <replaceable>cl_env</replaceable>.</para>
+
+ <para>This function implements the equivalent of <ulink url="&clhs;f_symb_5.htm"><symbol>symbol-value</symbol></ulink> and works both on special variables and constants.</para>
+
+ <para>If the symbol is not bound, an error is signaled.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="ref.ecl_va_arg">
+ <refnamediv>
+ <refname><function>ecl_va_arg</function></refname>
+ <refpurpose>Accepting a variable number of arguments</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macros</title>
+
+ <synopsis><type>typedef struct { ... } ecl_va_list[1];</type></synopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef><function>ecl_va_start</function></funcdef>
+ <paramdef>ecl_va_list <parameter>arglist</parameter></paramdef>
+ <paramdef><parameter>last_argument</parameter></paramdef>
+ <paramdef><parameter>narg</parameter></paramdef>
+ <paramdef><parameter>n_ordinary</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_va_arg</function></funcdef>
+ <paramdef>ecl_va_list <parameter>arglist</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_va_end</function></funcdef>
+ <paramdef>ecl_va_list <parameter>arglist</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The macros above are used to code a function that accepts an arbitrary number of arguments. We will describe them in a practical example</para>
+ <programlisting>
+cl_object my_plus(cl_narg narg, cl_object required1, ...)
+{
+ cl_env_ptr env = ecl_process_env();
+ cl_object other_value;
+ ecl_va_list varargs;
+ ecl_va_start(varargs, required1, narg, 1);
+ while (narg > 1) {
+ cl_object other_value = ecl_va_arg(varargs);
+ required1 = ecl_plus(required1, other_value);
+ }
+ ecl_va_end(varargs);
+ ecl_return1(env, required1);
+}
+ </programlisting>
+
+ <para>The first thing to do is to declare the variable that will hold the arguments. This is <replaceable>varargs</replaceable> in our example and it has the type <type>ecl_va_list</type>.</para>
+
+ <para>This arguments list is initialized with the <function>ecl_va_start</function> macro, based on the supplied number of arguments, <replaceable>narg</replaceable>, the number of required arguments which are passed as ordinary C arguments (1 in this case), the last such ordinary arguments, <replaceable>required</replaceable>, and the buffer for the argument list, <replaceable>varargs</replaceable>.</para>
+
+ <para>Once <replaceable>varargs</replaceable> has been initialized, we can retrieve these values one by one using <function>ecl_va_arg</function>. Note that the returned value always has the type <type>cl_object</type>, for it is always a Common Lisp object.</para>
+
+ <para>The last statement before returning the output of the function is <function>ecl_va_end</function>. This macro performs any required cleanup and should never be omitted.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname><function>ecl_nth_value</function>, <function>ecl_nvalues</function></refname>
+ <refpurpose>Accessing output values</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Functions and macros</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_nvalues</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>env</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis xml:id="ecl_nth_value">
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_nth_value</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>env</parameter></paramdef>
+ <paramdef>int <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>Common Lisp functions may return zero, one or more values. In &ECL;, the first two cases do not require any special manipulation, as the C function returns either <symbol>NIL</symbol> or the first (zeroth) value directly. However, if one wishes to access additional values from a function, one needs to use these two macros or functions</para>
+ <itemizedlist>
+ <listitem><para><code>ecl_nvalues(env)</code> returns the number of values that the function actually outputs. The single argument is the <link linkend="ecl_process_env">lisp environment</link>. This value is larger or equal to 0 and smaller than <constant>ECL_MULTIPLE_VALUES_LIMIT</constant>.</para></listitem>
+
+ <listitem><para>Once we know the number of return values, they can be directly accessed using the function <code>ecl_nth_value(env,n)</code>, where <replaceable>n</replaceable> is a number larger than or equal to 1, and smaller than <constant>ECL_MULTIPLE_VALUES_LIMIT</constant>, which must correspond to a valid output value. No checking is done.</para></listitem>
+ </itemizedlist>
+
+ <para>Note that in both cases these macros and functions have to be used right after the Lisp function was called. This is so because other Lisp functions might destroy the content of the return stack.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>A C/C++ exceprt</para>
+<programlisting>
+cl_env_ptr env = ecl_process_env();
+cl_object a = ecl_make_fixnum(13);
+cl_object b = ecl_make_fixnum(6);
+cl_object modulus = cl_floor(2, a, b);
+cl_object remainder = ecl_nth_value(env, 1);
+</programlisting>
+ <para>The somewhat equivalent Common Lisp code</para>
+<programlisting>
+(multiple-value-bind (modulus equivalent)
+ (floor 13 6))
+</programlisting>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname><function>ecl_return0</function>, <function>ecl_return1</function>, ...</refname>
+ <refpurpose>Returning multiple values</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef><function>ecl_return0</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>cl_env</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef><function>ecl_return1</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>cl_env</parameter></paramdef>
+ <paramdef>cl_object <parameter>value1</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef><function>ecl_return2</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>cl_env</parameter></paramdef>
+ <paramdef>cl_object <parameter>value1</parameter></paramdef>
+ <paramdef>cl_object <parameter>value2</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef><function>ecl_return3</function></funcdef>
+ <paramdef>cl_env_ptr <parameter>cl_env</parameter></paramdef>
+ <paramdef>cl_object <parameter>value1</parameter></paramdef>
+ <paramdef>cl_object <parameter>value2</parameter></paramdef>
+ <paramdef>cl_object <parameter>value3</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Returns <replaceable>N</replaceable> values from a C/C++ function in a way that a Common Lisp function can recognize and use them. The 0-th value is returned directly, while values 1 to N are stored in the Common Lisp environment <replaceable>cl_env</replaceable>. This macro has to be used from a function which returns an object of type <type>cl_object</type>.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname><function>ECL_BLOCK_BEGIN</function></refname>
+ <refpurpose>C macro for <ulink url="&clhs;s_block.htm"><symbol>block</symbol></ulink></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <synopsis><code><function>ECL_BLOCK_BEGIN</function>(env,code) {</code></synopsis>
+ <synopsis><code>} <function>ECL_BLOCK_END</function>;</code></synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ECL_BLOCK_BEGIN</function> establishes a block named <replaceable>code</replaceable> that becomes visible for the Common Lisp code. This block can be used then as a target for <function>cl_return</function>.</para>
+
+ <para><replaceable>env</replaceable> must be the value of the current Common Lisp environment, obtained with <function>ecl_process_env</function>.</para>
+
+ <para>The C/C++ program has to ensure that the code in <function>ECL_BLOCK_END</function> gets executed, avoiding a direct exit of the block via <code>goto</code> or a C/C++ <code>return</code>.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname><function>ECL_CATCH_BEGIN</function></refname>
+ <refpurpose>C macro for <ulink url="&clhs;s_catch.htm"><symbol>catch</symbol></ulink></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <synopsis><code><function>ECL_CATCH_BEGIN</function>(env,tag) {</code></synopsis>
+ <synopsis><code>} <function>ECL_CATCH_END</function>;</code></synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ECL_CATCH_BEGIN</function> establishes a destination for <symbol>throw</symbol> with the code given by <replaceable>tag</replaceable>.</para>
+
+ <para><replaceable>env</replaceable> must be the value of the current Common Lisp environment, obtained with <function>ecl_process_env</function>.</para>
+
+ <para>The C/C++ program has to ensure that the code in <function>ECL_CATCH_END</function> gets executed, avoiding a direct exit of the catch block via <code>goto</code> or a C/C++ <code>return</code>.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname><function>ECL_UNWIND_PROTECT_BEGIN</function></refname>
+ <refpurpose>C macro for <ulink url="&clhs;s_unwind.htm"><symbol>unwind-protect</symbol></ulink></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <synopsis><code><function>ECL_UNWIND_PROTECT_BEGIN</function>(env) {</code></synopsis>
+ <synopsis><code>} <function>ECL_UNWIND_PROTECT_EXIT</function> {</code></synopsis>
+ <synopsis><code>} <function>ECL_UNWIND_PROTECT_END</function>;</code></synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ECL_UNWIND_PROTECT_BEGIN</function> establishes two blocks of C code that work like the equivalent ones in Common Lisp: a protected block, contained between the "BEGIN" and the "EXIT" statement, and the exit block, appearing immediately afterwards. The form guarantees that the exit block is always executed, even if the protected block attempts to exit via som nonlocal jump construct (<symbol>throw</symbol>,<symbol>return</symbol>, etc).</para>
+
+ <para><replaceable>env</replaceable> must be the value of the current Common Lisp environment, obtained with <function>ecl_process_env</function>.</para>
+
+ <para>The utility of this construct is limited, for it only protects against nonlocal exits caused by Common Lisp constructs: it does not interfere with C <code>goto</code>, <code>return</code> or with C++ exceptions.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function or constant</member>
+
+<member><ulink url="&clhs;f_apply.htm"><symbol>apply</symbol></ulink></member>
+<member><code>cl_object cl_apply(cl_narg narg, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;v_call_a.htm"><symbol>call-arguments-limit</symbol></ulink></member>
+<member><constant>ECL_CALL_ARGUMENTS_LIMIT</constant></member>
+
+<member><ulink url="&clhs;f_cmpd_f.htm"><symbol>compiled-function-p</symbol></ulink></member>
+<member><code>cl_object cl_compiled_function_p(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_comple.htm"><symbol>complement</symbol></ulink></member>
+<member><code>cl_object cl_complement(cl_object function)</code></member>
+
+<member><ulink url="&clhs;f_cons_1.htm"><symbol>constantly</symbol></ulink></member>
+<member><code>cl_object cl_constantly(cl_object value)</code></member>
+
+<member><ulink url="&clhs;f_every.htm"><symbol>every</symbol></ulink></member>
+<member><code>cl_object cl_every(cl_narg narg, cl_object predicate, ...)</code></member>
+
+<member><ulink url="&clhs;f_eq.htm"><symbol>eq</symbol></ulink></member>
+<member><code>cl_object cl_eq(cl_object x, cl_object y)</code></member>
+
+<member><ulink url="&clhs;f_eql.htm"><symbol>eql</symbol></ulink></member>
+<member><code>cl_object cl_eql(cl_object x, cl_object y)</code></member>
+
+<member><ulink url="&clhs;f_equal.htm"><symbol>equal</symbol></ulink></member>
+<member><code>cl_object cl_equal(cl_object x, cl_object y)</code></member>
+
+<member><ulink url="&clhs;f_equalp.htm"><symbol>equalp</symbol></ulink></member>
+<member><code>cl_object cl_equalp(cl_object x, cl_object y)</code></member>
+
+<member><ulink url="&clhs;f_fbound.htm"><symbol>fboundp</symbol></ulink></member>
+<member><code>cl_object cl_fboundp(cl_object function_name)</code></member>
+
+<member><ulink url="&clhs;f_fdefin.htm"><symbol>fdefinition</symbol></ulink></member>
+<member><code>cl_object cl_fdefinition(cl_object function_name)</code></member>
+
+<member><ulink url="&clhs;f_fmakun.htm"><symbol>fmakunbound</symbol></ulink></member>
+<member><code>cl_object cl_fmakunbound(cl_object function_name)</code></member>
+
+<member><ulink url="&clhs;f_funcal.htm"><symbol>funcall</symbol></ulink></member>
+<member><code>cl_object cl_funcall(cl_narg narg, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;f_fn_lam.htm"><symbol>function-lambda-expression</symbol></ulink></member>
+<member><code>cl_object cl_function_lambda_expression(cl_object function)</code></member>
+
+<member><ulink url="&clhs;f_fnp.htm"><symbol>functionp</symbol></ulink></member>
+<member><code>cl_object cl_functionp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_get_se.htm"><symbol>get-setf-expansion</symbol></ulink></member>
+<member><code>cl_object cl_get_setf_expansion(cl_narg narg, cl_object place, ...)</code></member>
+
+<member><ulink url="&clhs;f_identi.htm"><symbol>identity</symbol></ulink></member>
+<member><code>cl_object cl_identity(cl_object x)</code></member>
+
+<member><ulink url="&clhs;s_let_l.htm"><symbol>LET</symbol>, <symbol>LET*</symbol></ulink></member>
+<member><code>cl_object <link linkend="ecl_bds_bind">ecl_bds_bind</link>(cl_env_ptr env, cl_object symbol, cl_object value)</code></member>
+
+<member><ulink url="&clhs;v_lamb_1.htm"><symbol>lambda-parameters-limit</symbol></ulink></member>
+<member><constant>ECL_LAMBDA_PARAMETERS_LIMIT</constant></member>
+
+<member><ulink url="&clhs;v_multip.htm"><symbol>multiple-values-limit</symbol></ulink></member>
+<member><constant>ECL_MULTIPLE_VALUES_LIMIT</constant></member>
+
+<member><ulink url="&clhs;f_not.htm"><symbol>not</symbol></ulink></member>
+<member><code>cl_object cl_not(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_notevery.htm"><symbol>notevery</symbol></ulink></member>
+<member><code>cl_object cl_notevery(cl_narg narg, cl_object predicate, ...)</code></member>
+
+<member><ulink url="&clhs;f_notany.htm"><symbol>notany</symbol></ulink></member>
+<member><code>cl_object cl_notany(cl_narg narg, cl_object predicate, ...)</code></member>
+
+<member><ulink url="&clhs;f_set.htm"><symbol>set</symbol></ulink></member>
+<member><code>cl_object cl_set(cl_object symbol, cl_object value)</code></member>
+
+<member><ulink url="&clhs;s_setq.htm"><symbol>setq</symbol></ulink></member>
+<member><code>cl_object <link linkend="ecl_setq">ecl_setq</link>(cl_env_ptr env, cl_object symbol, cl_object value)</code></member>
+
+<member><ulink url="&clhs;f_symb_5.htm"><symbol>symbol-value</symbol></ulink></member>
+<member><code>cl_object <link linkend="ecl_symbol_value">ecl_symbol_value</link>(cl_env_ptr env, cl_object symbol)</code></member>
+
+<member><ulink url="&clhs;f_some.htm"><symbol>some</symbol></ulink></member>
+<member><code>cl_object cl_some(cl_narg narg, cl_object predicate, ...)</code></member>
+
+<member><ulink url="&clhs;f_vals_l.htm"><symbol>values-list</symbol></ulink></member>
+<member><code>cl_object cl_values_list(cl_object list)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Environment</title>
+<section xml:id="ansi.environment.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_dec_un.htm"><symbol>decode-universal-time</symbol></ulink></member>
+<member><code>cl_object cl_decode_universal_time(cl_narg narg, cl_object universal_time, ...)</code></member>
+
+<member><ulink url="&clhs;f_encode.htm"><symbol>encode-universal-time</symbol></ulink></member>
+<member><code>cl_object cl_encode_universal_time(cl_narg narg, cl_object second, cl_object minute, cl_object hour, cl_object date, cl_object month, cl_object year, ...)</code></member>
+
+<member><ulink url="&clhs;f_get_un.htm"><symbol>get-universal-time</symbol></ulink></member>
+<member><code>cl_object cl_get_universal_time(void)</code></member>
+
+<member><ulink url="&clhs;f_get_un.htm"><symbol>get-decoded-time</symbol></ulink></member>
+<member><code>cl_object cl_get_decoded_time(void)</code></member>
+
+<member><ulink url="&clhs;f_sleep.htm"><symbol>sleep</symbol></ulink></member>
+<member><code>cl_object cl_sleep(cl_object seconds)</code></member>
+
+<member><ulink url="&clhs;f_apropo.htm"><symbol>apropos</symbol></ulink></member>
+<member><code>cl_object cl_apropos(cl_narg narg, cl_object string, ...)</code></member>
+
+<member><ulink url="&clhs;f_apropo.htm"><symbol>apropos-list</symbol></ulink></member>
+<member><code>cl_object cl_apropos_list(cl_narg narg, cl_object string, ...)</code></member>
+
+<member><ulink url="&clhs;f_descri.htm"><symbol>describe</symbol></ulink></member>
+<member><code>cl_object cl_describe(cl_narg narg, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_desc_1.htm"><symbol>describe-object</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_get_in.htm"><symbol>get-internal-real-time</symbol></ulink></member>
+<member><code>cl_object cl_get_internal_real_time()</code></member>
+
+<member><ulink url="&clhs;f_get__1.htm"><symbol>get-internal-run-time</symbol></ulink></member>
+<member><code>cl_object cl_get_internal_run_time()</code></member>
+
+<member><ulink url="&clhs;f_disass.htm"><symbol>disassemble</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_docume.htm"><symbol>documentation</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_room.htm"><symbol>room</symbol></ulink></member>
+<member><code>cl_object cl_room(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_ed.htm"><symbol>ed</symbol></ulink></member>
+<member><code>cl_object cl_ed(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_inspec.htm"><symbol>inspect</symbol></ulink></member>
+<member><code>cl_object cl_inspect(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_dribbl.htm"><symbol>dribble</symbol></ulink></member>
+<member><code>cl_object cl_dribble(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_lisp_i.htm"><symbol>lisp-implementation-type</symbol></ulink></member>
+<member><code>cl_object cl_lisp_implementation_type(void)</code></member>
+
+<member><ulink url="&clhs;f_lisp_i.htm"><symbol>lisp-implementation-version</symbol></ulink></member>
+<member><code>cl_object cl_lisp_implementation_version(void)</code></member>
+
+<member><ulink url="&clhs;f_short_.htm"><symbol>short-site-name</symbol></ulink></member>
+<member><code>cl_object cl_short_site_name()</code></member>
+
+<member><ulink url="&clhs;f_short_.htm"><symbol>long-site-name</symbol></ulink></member>
+<member><code>cl_object cl_long_site_name()</code></member>
+
+<member><ulink url="&clhs;f_mach_i.htm"><symbol>machine-instance</symbol></ulink></member>
+<member><code>cl_object cl_machine_instance()</code></member>
+
+<member><ulink url="&clhs;f_mach_t.htm"><symbol>machine-type</symbol></ulink></member>
+<member><code>cl_object cl_machine_type()</code></member>
+
+<member><ulink url="&clhs;f_mach_v.htm"><symbol>machine-version</symbol></ulink></member>
+<member><code>cl_object cl_machine_version()</code></member>
+
+<member><ulink url="&clhs;f_sw_tpc.htm"><symbol>software-type</symbol></ulink></member>
+<member><code>cl_object cl_software_type()</code></member>
+
+<member><ulink url="&clhs;f_sw_tpc.htm"><symbol>software-version</symbol></ulink></member>
+<member><code>cl_object cl_software_version()</code></member>
+
+<member><ulink url="&clhs;f_user_h.htm"><symbol>user-homedir-pathname</symbol></ulink></member>
+<member><code>cl_object cl_user_homedir_pathname()</code></member>
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Evaluation and compilation</title>
+<section xml:id="ansi.evaluation.c-dict">
+<title>C Reference</title>
+
+ <refentry xml:id="ecl_process_env">
+ <refnamediv>
+ <refname><function>ecl_process_env</function></refname>
+ <refpurpose>Per-thread environment</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_env_ptr <function>ecl_process_env</function></funcdef>
+ <paramdef></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>&ECL; stores information about each thread on a dedicated structure, which is the process environment. A pointer to this structure can be retrieved using the function or macro above. This pointer can be used for a variety of tasks, such as defining special variable bindings, controlling interrupts, retrieving function output values, etc.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_cmp.htm"><symbol>compile</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_eval.htm"><symbol>eval</symbol></ulink></member>
+<member><code>cl_object cl_eval(cl_object form)</code></member>
+
+<member><ulink url="&clhs;f_cmp_ma.htm"><symbol>compiler-macro-function</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_macro_.htm"><symbol>macro-function</symbol></ulink></member>
+<member><code>cl_object cl_macro_function(cl_narg narg, cl_object symbol, ...)</code></member>
+
+<member><ulink url="&clhs;f_mexp_.htm"><symbol>macroexpand</symbol></ulink></member>
+<member><code>cl_object cl_macroexpand(cl_narg narg, cl_object form, ...)</code></member>
+
+<member><ulink url="&clhs;f_mexp_.htm"><symbol>macroexpand-1</symbol></ulink></member>
+<member><code>cl_object cl_macroexpand_1(cl_narg narg, cl_object form, ...)</code></member>
+
+<member><ulink url="&clhs;f_procla.htm"><symbol>proclaim</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_specia.htm"><symbol>special-operator-p</symbol></ulink></member>
+<member><code>cl_object cl_special_operator_p(cl_object form)</code></member>
+
+<member><ulink url="&clhs;f_consta.htm"><symbol>constantp</symbol></ulink></member>
+<member><code>cl_object cl_constantp(cl_narg narg, cl_object form, ...)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Filenames</title>
+<section xml:id="ansi.filenames.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>Filenames C dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_namest.htm"><symbol>directory-namestring</symbol></ulink></member>
+<member><code>cl_object cl_directory_namestring(cl_object pathname)</code></member>
+
+<member><ulink url="&clhs;f_namest.htm"><symbol>enough-namestring</symbol></ulink></member>
+<member><code>cl_object cl_enough_namestring(cl_narg narg, cl_object pathname, ...)</code></member>
+
+<member><ulink url="&clhs;f_namest.htm"><symbol>file-namestring</symbol></ulink></member>
+<member><code>cl_object cl_file_namestring(cl_object pathname)</code></member>
+
+<member><ulink url="&clhs;f_namest.htm"><symbol>host-namestring</symbol></ulink></member>
+<member><code>cl_object cl_host_namestring(cl_object pathname)</code></member>
+
+<member><ulink url="&clhs;f_ld_log.htm"><symbol>load-logical-pathname-translations</symbol></ulink></member>
+<member><code>cl_object cl_load_logical_pathname_translations(cl_object host)</code></member>
+
+<member><ulink url="&clhs;f_logica.htm"><symbol>logical-pathname-translations</symbol></ulink></member>
+<member><code>cl_object cl_logical_pathname_translations(cl_object host)</code></member>
+
+<member><ulink url="&clhs;f_logi_1.htm"><symbol>logical-pathname</symbol></ulink></member>
+<member><code>cl_object cl_logical_pathname(cl_object pathspec)</code></member>
+
+<member><ulink url="&clhs;f_pn.htm.htm"><symbol>make-pathname</symbol></ulink></member>
+<member><code>cl_object cl_make_pathname(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_merge_.htm"><symbol>merge-pathnames</symbol></ulink></member>
+<member><code>cl_object cl_merge_pathnames(cl_narg narg, cl_object pathname,...)</code></member>
+
+<member><ulink url="&clhs;f_namest.htm"><symbol>namestring</symbol></ulink></member>
+<member><code>cl_object cl_namestring(cl_object pathname)</code></member>
+
+<member><ulink url="&clhs;f_pars_1.htm"><symbol>parse-namestring</symbol></ulink></member>
+<member><code>cl_object cl_parse_namestring(cl_narg narg, cl_object thing, ...)</code></member>
+
+<member><ulink url="&clhs;pathname"><symbol>pathname</symbol></ulink></member>
+<member><code>cl_object cl_pathname(cl_object pathspec)</code></member>
+
+<member><ulink url="&clhs;f_pn_hos.htm"><symbol>pathname-device</symbol></ulink></member>
+<member><code>cl_object cl_pathname_device(cl_narg narg, cl_object pathname, ...)</code></member>
+
+<member><ulink url="&clhs;f_pn_hos.htm"><symbol>pathname-directory</symbol></ulink></member>
+<member><code>cl_object cl_pathname_directory(cl_narg narg, cl_object pathname, ...)</code></member>
+
+<member><ulink url="&clhs;f_pn_hos.htm"><symbol>pathname-host</symbol></ulink></member>
+<member><code>cl_object cl_pathname_host(cl_narg narg, cl_object pathname, ...)</code></member>
+
+<member><ulink url="&clhs;f_pn_mat.htm"><symbol>pathname-match-p</symbol></ulink></member>
+<member><code>cl_object cl_pathname_match_p(cl_object pathname, cl_object wildcard)</code></member>
+
+<member><ulink url="&clhs;f_pn_hos.htm"><symbol>pathname-name</symbol></ulink></member>
+<member><code>cl_object cl_pathname_name(cl_narg narg, cl_object pathname, ...)</code></member>
+
+<member><ulink url="&clhs;f_pn_hos.htm"><symbol>pathname-type</symbol></ulink></member>
+<member><code>cl_object cl_pathname_type(cl_narg narg, cl_object pathname, ...)</code></member>
+
+<member><ulink url="&clhs;f_pn_hos.htm"><symbol>pathname-version</symbol></ulink></member>
+<member><code>cl_object cl_pathname_version(cl_object pathname)</code></member>
+
+<member><ulink url="&clhs;f_pnp.htm"><symbol>pathnamep</symbol></ulink></member>
+<member><code>cl_object cl_pathnamep(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_tr_log.htm"><symbol>translate-logical-pathname</symbol></ulink></member>
+<member><code>cl_object cl_translate_logical_pathname(cl_narg narg, cl_object pathname, ...)</code></member>
+
+<member><ulink url="&clhs;f_tr_pn.htm"><symbol>translate-pathname</symbol></ulink></member>
+<member><code>cl_object cl_translate_pathname(cl_narg narg, cl_object source, cl_object from_wildcard, cl_object to_wildcard, ...)</code></member>
+
+<member><ulink url="&clhs;f_wild_p.htm"><symbol>wild-pathname-p</symbol></ulink></member>
+<member><code>cl_object cl_wild_pathname_p(cl_narg narg, cl_object pathname, ...)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Files</title>
+<section xml:id="ansi.files.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>Files C dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_del_fi.htm"><symbol>delete-file</symbol></ulink></member>
+<member><code>cl_object cl_delete_file(cl_object filespec)</code></member>
+
+<member><ulink url="&clhs;f_dir.htm"><symbol>directory</symbol></ulink></member>
+<member><code>cl_object cl_directory(cl_narg narg, cl_object pathspec, ...)</code></member>
+
+<member><ulink url="&clhs;f_ensu_1.htm"><symbol>ensure-directories-exist</symbol></ulink></member>
+<member><code>cl_object cl_ensure_directories_exist(cl_narg narg, cl_object pathspec, ...)</code></member>
+
+<member><ulink url="&clhs;f_file_a.htm"><symbol>file-author</symbol></ulink></member>
+<member><code>cl_object cl_file_author(cl_object pathspec)</code></member>
+
+<member><ulink url="&clhs;f_file_e.htm"><symbol>file-error-pathname</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_file_w.htm"><symbol>file-write-date</symbol></ulink></member>
+<member><code>cl_object cl_file_write_date(cl_object pathspec)</code></member>
+
+<member><ulink url="&clhs;f_probe_.htm"><symbol>probe-file</symbol></ulink></member>
+<member><code>cl_object cl_probe_file(cl_object pathspec)</code></member>
+
+<member><ulink url="&clhs;f_rn_fil.htm"><symbol>rename-file</symbol></ulink></member>
+<member><code>cl_object cl_rename_file(cl_object filespec, cl_object new_name)</code></member>
+
+<member><ulink url="&clhs;f_tn.htm"><symbol>truename</symbol></ulink></member>
+<member><code>cl_object cl_truename(cl_object filespec)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Hash Tables</title>
+<section xml:id="ansi.hash-tables.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>Hash tables C dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_clrhas.htm"><symbol>clrhash</symbol></ulink></member>
+<member><code>cl_object cl_clrhash(cl_object hash_table)</code></member>
+
+<member><ulink url="&clhs;f_gethas.htm"><symbol>gethash</symbol></ulink></member>
+<member><code>cl_object cl_gethash(cl_narg narg, cl_object key, cl_object hash_table, ...)</code></member>
+
+<member><ulink url="&clhs;f_hash_1.htm"><symbol>hash-table-count</symbol></ulink></member>
+<member><code>cl_object cl_hash_table_count(cl_object hash_table)</code></member>
+
+<member><ulink url="&clhs;f_hash_t.htm"><symbol>hash-table-p</symbol></ulink></member>
+<member><code>cl_object cl_hash_table_p(cl_object hash_table)</code></member>
+
+<member><ulink url="&clhs;f_hash_2.htm"><symbol>hash-table-rehash-size</symbol></ulink></member>
+<member><code>cl_object cl_hash_table_rehash_size(cl_object hash_table)</code></member>
+
+<member><ulink url="&clhs;f_hash_3.htm"><symbol>hash-table-rehash-threshold</symbol></ulink></member>
+<member><code>cl_object cl_hash_table_rehash_thresholdy(cl_object hash_table)</code></member>
+
+<member><ulink url="&clhs;f_hash_4.htm"><symbol>hash-table-size</symbol></ulink></member>
+<member><code>cl_object cl_hash_table_size(cl_object hash_table)</code></member>
+
+<member><ulink url="&clhs;f_hash_5.htm"><symbol>hash-table-test</symbol></ulink></member>
+<member><code>cl_object cl_hash_table_test(cl_object hash_table)</code></member>
+
+<member><ulink url="&clhs;f_mk_has.htm"><symbol>make-hash-table</symbol></ulink></member>
+<member><code>cl_object cl_make_hash_table(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_maphas.htm"><symbol>maphash</symbol></ulink></member>
+<member><code>cl_object cl_maphash(cl_object function, cl_object hash_table)</code></member>
+
+<member><ulink url="&clhs;f_remhas.htm"><symbol>remhash</symbol></ulink></member>
+<member><code>cl_object cl_remhash(cl_object key, cl_object hash_table)</code></member>
+
+<member><ulink url="&clhs;f_sxhash.htm"><symbol>sxhash</symbol></ulink></member>
+<member><code>cl_object cl_sxhash(cl_object object)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Numbers</title>
+<section xml:id="ansi.numbers.c-dict">
+<title>C Reference</title>
+
+ <refentry xml:id="ansi.numbers.c-types">
+ <refnamediv>
+ <refname>Number C types</refname>
+ <refpurpose>Numeric C types understood by ECL</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Type names</title>
+ <simplelist columns="4" type="horiz">
+ <member><type>cl_fixnum</type></member>
+ <member><type>fixnum</type></member>
+ <member></member>
+ <member></member>
+
+ <member><type>cl_index</type></member>
+ <member><type>(integer 0 most-positive-fixnum)</type></member>
+ <member></member>
+ <member></member>
+
+ <member><type>float</type></member>
+ <member><type>short-float</type>, <type>single-float</type></member>
+ <member></member>
+ <member></member>
+
+ <member><type>double</type></member>
+ <member><type>double-float</type></member>
+ <member></member>
+ <member></member>
+
+ <member><type>long double</type> (*)</member>
+ <member><type>long-float</type></member>
+ <member><constant>ECL_LONG_FLOAT</constant></member>
+ <member><symbol>:long-float</symbol></member>
+
+ <member><type>uint8_t</type></member>
+ <member><type>(unsigned-byte 8)</type></member>
+ <member></member>
+ <member></member>
+
+ <member><type>int8_t</type></member>
+ <member><type>(signed-byte 8)</type></member>
+ <member></member>
+ <member></member>
+
+ <member><type>uint16_t</type></member>
+ <member><type>(unsigned-byte 16)</type></member>
+ <member><constant>ecl_uint16_t</constant></member>
+ <member><symbol>:uint16-t</symbol></member>
+
+ <member><type>int16_t</type></member>
+ <member><type>(signed-byte 16)</type></member>
+ <member><constant>ecl_int16_t</constant></member>
+ <member><symbol>:uint16-t</symbol></member>
+
+ <member><type>uint32_t</type></member>
+ <member><type>(unsigned-byte 32)</type></member>
+ <member><constant>ecl_uint32_t</constant></member>
+ <member><symbol>:uint32-t</symbol></member>
+
+ <member><type>int32_t</type></member>
+ <member><type>(signed-byte 32)</type></member>
+ <member><constant>ecl_int32_t</constant></member>
+ <member><symbol>:uint32-t</symbol></member>
+
+ <member><type>uint64_t</type></member>
+ <member><type>(unsigned-byte 64)</type></member>
+ <member><constant>ecl_uint32_t</constant></member>
+ <member><symbol>:uint32-t</symbol></member>
+
+ <member><type>int64_t</type></member>
+ <member><type>(signed-byte 64)</type></member>
+ <member><constant>ecl_int64_t</constant></member>
+ <member><symbol>:uint32-t</symbol></member>
+
+ <member><type>short</type></member>
+ <member><type>(integer ffi:c-short-min ffi:c-short-max)</type></member>
+ <member><constant>ecl_uint64_t</constant></member>
+ <member><symbol>:uint32-t</symbol></member>
+
+ <member><type>unsigned short </type></member>
+ <member><type>(integer 0 ffi:c-ushort-max)</type></member>
+ <member></member>
+ <member></member>
+
+ <member><type>int</type></member>
+ <member><type>(integer ffi:c-int-min ffi:c-int-max)</type></member>
+ <member></member>
+ <member></member>
+
+ <member><type>unsigned int </type></member>
+ <member><type>(integer 0 ffi:c-uint-max)</type></member>
+ <member></member>
+ <member></member>
+
+ <member><type>long</type></member>
+ <member><type>(integer ffi:c-long-min ffi:c-long-max)</type></member>
+ <member></member>
+ <member></member>
+
+ <member><type>unsigned long </type></member>
+ <member><type>(integer 0 ffi:c-long-max)</type></member>
+ <member></member>
+ <member></member>
+
+ <member><type>long long</type></member>
+ <member><type>(integer ffi:c-long-long-min ffi:c-long-long-max)</type></member>
+ <member><constant>ecl_long_long_t</constant></member>
+ <member><symbol>:long-long</symbol></member>
+
+ <member><type>unsigned long long</type></member>
+ <member><type>(integer 0 ffi:c-ulong-long-max)</type></member>
+ <member><constant>ecl_ulong_long_t</constant></member>
+ <member><symbol>:long-long</symbol></member>
+ </simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The table above shows the relation between C types and the equivalent Common Lisp types. All types are standard <acronym>C99</acronym> types, except for two. First, <type>cl_fixnum</type> is the smallest signed integer that can fit a <type>fixnum</type>. Second, <type>cl_index</type> is the smallest unsigned integer that fits a fixnum and is typically the unsigned counterpart of <type>cl_fixnum</type>.</para>
+
+ <para>(*) The <type>long double</type> does not exist on all platforms. When it exists, the macro <constant>ECL_LONG_DOUBLE</constant> will be defined, and <type>long-double</type> will be equivalent to it.</para>
+
+ <para>Many other types might also not exist on all platforms. This includes not only <type>long long</type> and <type>unsigned long long</type>, but also some of the <acronym>C99</acronym> integer types. There are two ways to detect which integer types are available in your system</para>
+ <itemizedlist>
+ <listitem><para>Check for the definition of C macros with a similar name, shown in the fourth column above.</para></listitem>
+ <listitem><para>In Lisp code, check for the presence of the associated features, shown in the fifth column above.</para></listitem>
+ </itemizedlist>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>Number constructors</refname>
+ <refpurpose>Creating Lisp types from C numbers</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Functions and macros</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_fixnum</function></funcdef>
+ <paramdef><type>cl_fixnum</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_integer</function></funcdef>
+ <paramdef><type>cl_fixnum</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_unsigned_integer</function></funcdef>
+ <paramdef><type>cl_index</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_single_float</function></funcdef>
+ <paramdef><type>float</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_double_float</function></funcdef>
+ <paramdef><type>double</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_long_float</function></funcdef>
+ <paramdef><type>long double</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_uint8_t</function></funcdef>
+ <paramdef><type>uint8_t</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_int8_t</function></funcdef>
+ <paramdef><type>int8_t</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_uint16_t</function></funcdef>
+ <paramdef><type>uint16_t</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_int16_t</function></funcdef>
+ <paramdef><type>int16_t</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_uint32_t</function></funcdef>
+ <paramdef><type>uint32_t</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_int32_t</function></funcdef>
+ <paramdef><type>int32_t</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_uint64_t</function></funcdef>
+ <paramdef><type>uint64_t</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_int64_t</function></funcdef>
+ <paramdef><type>int64_t</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_short</function></funcdef>
+ <paramdef><type>short</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_ushort</function></funcdef>
+ <paramdef><type>unsigned short</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_int</function></funcdef>
+ <paramdef><type>int</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_uint</function></funcdef>
+ <paramdef><type>unsigned int</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_long</function></funcdef>
+ <paramdef><type>long</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_ulong</function></funcdef>
+ <paramdef><type>unsigned long</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_long_long</function></funcdef>
+ <paramdef><type>long long</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_ulong_long</function></funcdef>
+ <paramdef><type>unsigned long long</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_ratio</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>numerator</parameter></paramdef>
+ <paramdef><type>cl_object</type> <parameter>denominator</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_complex</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>real</parameter></paramdef>
+ <paramdef><type>cl_object</type> <parameter>imag</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>These functions create a Lisp object from the corresponding C number. If the number is an integer type, the result will always be an integer, which may be a <type>bignum</type>. If on the other hand the C number is a <type>float</type>, <type>double</type> or <type>long double</type>, the result will be a <type>float</type>.</para>
+
+ <para>There is some redundancy in the list of functions that convert from <type>cl_fixnum</type> and <type>cl_index</type> to lisp. On the one hand, <function>ecl_make_fixnum()</function> always creates a fixnum, dropping bits if necessary. On the other hand, <function>ecl_make_integer</function> and <function>ecl_make_unsigned_integer</function> faithfully converts to a Lisp integer, which may a bignum.</para>
+
+ <para>Note also that some of the constructors do not use C numbers. This is the case of <function>ecl_make_ratio</function> and <function>ecl_make_complex</function>, because they are composite Lisp types.</para>
+
+ <para>These functions or macros signal no errors.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>Number accessors</refname>
+ <refpurpose>Unchecked conversion from Lisp types to C numbers</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Functions and macros</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_fixnum <function>ecl_fixnum</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>float <function>ecl_single_float</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>double <function>ecl_double_float</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>long double <function>ecl_long_float</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>These functions and macros extract a C number from a Lisp object. They do not check the type of the Lisp object as they typically just access directly the value from a C structure.</para>
+ </refsect1>
+
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>Number coercion</refname>
+ <refpurpose>Checked conversion from Lisp types to C numbers</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Functions and macros</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_fixnum <function>ecl_to_fixnum</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_index <function>ecl_to_unsigned_integer</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>flaot <function>ecl_to_float</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>double <function>ecl_to_double</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>long double <function>ecl_to_long_double</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>float <function>ecl_to_float</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>int8_t <function>ecl_to_uint8_t</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>int8_t <function>ecl_to_int8_t</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>uint16_t <function>ecl_to_uint16_t</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>int16_t <function>ecl_to_int16_t</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>uint32_t <function>ecl_to_uint32_t</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>int32_t <function>ecl_to_int32_t</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>uint64_t <function>ecl_to_uint64_t</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>int64_t <function>ecl_to_int64_t</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>short <function>ecl_to_short</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>unsigned short <function>ecl_to_ushort</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>int <function>ecl_to_int</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>unsigned int <function>ecl_to_uint</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>long <function>ecl_to_long</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>unsigned long <function>ecl_to_ulong</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>long long <function>ecl_to_long_long</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>unsigned long long <function>ecl_to_ulong_long</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>n</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>These functions and macros convert a Lisp object to the corresponding C number type. The conversion is done through a coercion process which may signal an error if the argument does not fit the expected type.</para>
+ </refsect1>
+
+ </refentry>
+
+ <refentry xml:id="ansi.numbers.c-dict.ref">
+ <refnamediv>
+ <refname>Numbers C dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_eq_sle.htm"><symbol>=</symbol></ulink></member>
+<member><code>cl_object cl_E()</code></member>
+
+<member><ulink url="&clhs;f_eq_sle.htm"><symbol>/=</symbol></ulink></member>
+<member><code>cl_object cl_NE()</code></member>
+
+<member><ulink url="&clhs;f_eq_sle.htm"><symbol><</symbol></ulink></member>
+<member><code>cl_object cl_L()</code></member>
+
+<member><ulink url="&clhs;f_eq_sle.htm"><symbol>></symbol></ulink></member>
+<member><code>cl_object cl_G()</code></member>
+
+<member><ulink url="&clhs;f_eq_sle.htm"><symbol><=</symbol></ulink></member>
+<member><code>cl_object cl_LE()</code></member>
+
+<member><ulink url="&clhs;f_eq_sle.htm"><symbol>>=</symbol></ulink></member>
+<member><code>cl_object cl_GE()</code></member>
+
+<member><ulink url="&clhs;f_max_m.htm"><symbol>max</symbol></ulink></member>
+<member><code>cl_object cl_max(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_max_m.htm"><symbol>min</symbol></ulink></member>
+<member><code>cl_object cl_min(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_minusp.htm"><symbol>minusp</symbol></ulink></member>
+<member><code>cl_object cl_minusp(cl_object real)</code></member>
+
+<member><ulink url="&clhs;f_minusp.htm"><symbol>plusp</symbol></ulink></member>
+<member><code>cl_object cl_plusp(cl_object real)</code></member>
+
+<member><ulink url="&clhs;f_zerop.htm"><symbol>zerop</symbol></ulink></member>
+<member><code>cl_object cl_zerop(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_floorc.htm"><symbol>floor</symbol></ulink></member>
+<member><code>cl_object cl_floor(cl_narg narg, cl_object number, ...)</code></member>
+
+<member><ulink url="&clhs;f_floorc.htm"><symbol>ffloor</symbol></ulink></member>
+<member><code>cl_object cl_ffloor(cl_narg narg, cl_object number, ...)</code></member>
+
+<member><ulink url="&clhs;f_floorc.htm"><symbol>ceiling</symbol></ulink></member>
+<member><code>cl_object cl_ceiling(cl_narg narg, cl_object number, ...)</code></member>
+
+<member><ulink url="&clhs;f_floorc.htm"><symbol>fceiling</symbol></ulink></member>
+<member><code>cl_object cl_fceiling(cl_narg narg, cl_object number, ...)</code></member>
+
+<member><ulink url="&clhs;f_floorc.htm"><symbol>truncate</symbol></ulink></member>
+<member><code>cl_object cl_truncate(cl_narg narg, cl_object number, ...)</code></member>
+
+<member><ulink url="&clhs;f_floorc.htm"><symbol>ftruncate</symbol></ulink></member>
+<member><code>cl_object cl_ftruncate(cl_narg narg, cl_object number, ...)</code></member>
+
+<member><ulink url="&clhs;f_floorc.htm"><symbol>round</symbol></ulink></member>
+<member><code>cl_object cl_round(cl_narg narg, cl_object number, ...)</code></member>
+
+<member><ulink url="&clhs;f_floorc.htm"><symbol>fround</symbol></ulink></member>
+<member><code>cl_object cl_fround(cl_narg narg, cl_object number, ...)</code></member>
+
+<member><ulink url="&clhs;f_sin_c.htm"><symbol>sin</symbol></ulink></member>
+<member><code>cl_object cl_sin(cl_object radians)</code></member>
+
+<member><ulink url="&clhs;f_sin_c.htm"><symbol>cos</symbol></ulink></member>
+<member><code>cl_object cl_cos(cl_object radians)</code></member>
+
+<member><ulink url="&clhs;f_sin_c.htm"><symbol>tan</symbol></ulink></member>
+<member><code>cl_object cl_tan(cl_object radians)</code></member>
+
+<member><ulink url="&clhs;f_asin_.htm"><symbol>asin</symbol></ulink></member>
+<member><code>cl_object cl_asin(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_asin_.htm"><symbol>acos</symbol></ulink></member>
+<member><code>cl_object cl_acos(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_asin_.htm"><symbol>atan</symbol></ulink></member>
+<member><code>cl_object cl_atan(cl_narg narg, cl_object number1, ...)</code></member>
+
+<member><ulink url="&clhs;c_number.htm"><symbol>sinh</symbol></ulink></member>
+<member><code>cl_object cl_sinh(cl_object number)</code></member>
+
+<member><ulink url="&clhs;c_number.htm"><symbol>cosh</symbol></ulink></member>
+<member><code>cl_object cl_cosh(cl_object number)</code></member>
+
+<member><ulink url="&clhs;c_number.htm"><symbol>tanh</symbol></ulink></member>
+<member><code>cl_object cl_tanh(cl_object number)</code></member>
+
+<member><ulink url="&clhs;c_number.htm"><symbol>asinh</symbol></ulink></member>
+<member><code>cl_object cl_asinh(cl_object number)</code></member>
+
+<member><ulink url="&clhs;c_number.htm"><symbol>cosh</symbol></ulink></member>
+<member><code>cl_object cl_acosh(cl_object number)</code></member>
+
+<member><ulink url="&clhs;c_number.htm"><symbol>atanh</symbol></ulink></member>
+<member><code>cl_object cl_atanh(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_st.htm"><symbol>*</symbol></ulink></member>
+<member><code>cl_object cl_X(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_pl.htm"><symbol>+</symbol></ulink></member>
+<member><code>cl_object cl_P(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f__.htm"><symbol>-</symbol></ulink></member>
+<member><code>cl_object cl_M(cl_narg narg, cl_object number, ...)</code></member>
+
+<member><ulink url="&clhs;f_sl.htm"><symbol>/</symbol></ulink></member>
+<member><code>cl_object cl_N(cl_narg narg, cl_object number, ...)</code></member>
+
+<member><ulink url="&clhs;f_1pl_1_.htm"><symbol>1+</symbol></ulink></member>
+<member><code>cl_object cl_1P()</code></member>
+
+<member><ulink url="&clhs;f_1pl_1_.htm"><symbol>1-</symbol></ulink></member>
+<member><code>cl_object cl_1M()</code></member>
+
+<member><ulink url="&clhs;f_abs.htm"><symbol>abs</symbol></ulink></member>
+<member><code>cl_object cl_abs(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_evenpc.htm"><symbol>evenp</symbol></ulink></member>
+<member><code>cl_object cl_evenp(cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_evenpc.htm"><symbol>oddp</symbol></ulink></member>
+<member><code>cl_object cl_oddp(cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_exp_e.htm"><symbol>exp</symbol></ulink></member>
+<member><code>cl_object cl_exp(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_exp_e.htm"><symbol>expt</symbol></ulink></member>
+<member><code>cl_object cl_expt(cl_object base, cl_object power)</code></member>
+
+<member><ulink url="&clhs;f_gcd.htm"><symbol>gcd</symbol></ulink></member>
+<member><code>cl_object cl_gcd(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_lcm.htm"><symbol>lcm</symbol></ulink></member>
+<member><code>cl_object cl_lcm(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_log.htm"><symbol>log</symbol></ulink></member>
+<member><code>cl_object cl_log(cl_narg narg, cl_object number, ...)</code></member>
+
+<member><ulink url="&clhs;f_mod_r.htm"><symbol>mod</symbol></ulink></member>
+<member><code>cl_object cl_mod(cl_object number, cl_object divisor)</code></member>
+
+<member><ulink url="&clhs;f_mod_r.htm"><symbol>rem</symbol></ulink></member>
+<member><code>cl_object cl_rem(cl_object number, cl_object divisor)</code></member>
+
+<member><ulink url="&clhs;f_signum.htm"><symbol>signum</symbol></ulink></member>
+<member><code>cl_object cl_signum(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_sqrt_.htm"><symbol>sqrt</symbol></ulink></member>
+<member><code>cl_object cl_sqrt(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_sqrt_.htm"><symbol>isqrt</symbol></ulink></member>
+<member><code>cl_object cl_isqrt(cl_object natural)</code></member>
+
+<member><ulink url="&clhs;f_mk_rnd.htm"><symbol>make-random-state</symbol></ulink></member>
+<member><code>cl_object cl_make_random_state(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_random.htm"><symbol>random</symbol></ulink></member>
+<member><code>cl_object cl_random(cl_narg narg, cl_object limit, ...)</code></member>
+
+<member><ulink url="&clhs;f_rnd_st.htm"><symbol>random-state-p</symbol></ulink></member>
+<member><code>cl_object cl_random_state_p(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_nump.htm"><symbol>numberp</symbol></ulink></member>
+<member><code>cl_object cl_numberp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_cis.htm"><symbol>cis</symbol></ulink></member>
+<member><code>cl_object cl_cis(cl_object radians)</code></member>
+
+<member><ulink url="&clhs;f_comp_2.htm"><symbol>complex</symbol></ulink></member>
+<member><code>cl_object cl_complex(cl_narg narg, cl_object realpart, ...)</code></member>
+
+<member><ulink url="&clhs;f_comp_3.htm"><symbol>complexp</symbol></ulink></member>
+<member><code>cl_object cl_complexp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_conjug.htm"><symbol>conjugate</symbol></ulink></member>
+<member><code>cl_object cl_conjugate(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_phase.htm"><symbol>phase</symbol></ulink></member>
+<member><code>cl_object cl_phase(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_realpa.htm"><symbol>realpart</symbol></ulink></member>
+<member><code>cl_object cl_realpart(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_realpa.htm"><symbol>imagpart</symbol></ulink></member>
+<member><code>cl_object cl_imagpart(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_upgrad.htm"><symbol>upgraded-complex-part-type</symbol></ulink></member>
+<member><code>cl_object cl_upgraded_complex_part_type(cl_narg narg, cl_object typespec, ...)</code></member>
+
+<member><ulink url="&clhs;f_realp.htm"><symbol>realp</symbol></ulink></member>
+<member><code>cl_object cl_realp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_numera.htm"><symbol>numerator</symbol></ulink></member>
+<member><code>cl_object cl_numerator(cl_object rational)</code></member>
+
+<member><ulink url="&clhs;f_numera.htm"><symbol>denominator</symbol></ulink></member>
+<member><code>cl_object cl_denominator(cl_object rational)</code></member>
+
+<member><ulink url="&clhs;f_ration.htm"><symbol>rational</symbol></ulink></member>
+<member><code>cl_object cl_rational(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_ration.htm"><symbol>rationalize</symbol></ulink></member>
+<member><code>cl_object cl_rationalize(cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_rati_1.htm"><symbol>rationalp</symbol></ulink></member>
+<member><code>cl_object cl_rationalp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_ash.htm"><symbol>ash</symbol></ulink></member>
+<member><code>cl_object cl_ash(cl_object integer, cl_object count)</code></member>
+
+<member><ulink url="&clhs;f_intege.htm"><symbol>integer-length</symbol></ulink></member>
+<member><code>cl_object cl_integer_length(cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_inte_1.htm"><symbol>integerp</symbol></ulink></member>
+<member><code>cl_object cl_integerp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_parse_.htm"><symbol>parse-integer</symbol></ulink></member>
+<member><code>cl_object cl_parse_integer(cl_narg narg, cl_object string, ...)</code></member>
+
+<member><ulink url="&clhs;f_boole.htm"><symbol>boole</symbol></ulink></member>
+<member><code>cl_object cl_boole(cl_object op, cl_object integer1, cl_object integer2)</code></member>
+
+<member><ulink url="&clhs;f_logand.htm"><symbol>logand</symbol></ulink></member>
+<member><code>cl_object cl_logand(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_logand.htm"><symbol>logandc1</symbol></ulink></member>
+<member><code>cl_object cl_logandc1(cl_object integer1, cl_object integer2)</code></member>
+
+<member><ulink url="&clhs;f_logand.htm"><symbol>logandc2</symbol></ulink></member>
+<member><code>cl_object cl_logandc2(cl_object integer1, cl_object integer2)</code></member>
+
+<member><ulink url="&clhs;f_logand.htm"><symbol>logeqv</symbol></ulink></member>
+<member><code>cl_object cl_logeqv(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_logand.htm"><symbol>logior</symbol></ulink></member>
+<member><code>cl_object cl_logior(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_logand.htm"><symbol>lognand</symbol></ulink></member>
+<member><code>cl_object cl_lognand(cl_object integer1, cl_object integer2)</code></member>
+
+<member><ulink url="&clhs;f_logand.htm"><symbol>lognor</symbol></ulink></member>
+<member><code>cl_object cl_lognor(cl_object integer1, cl_object integer2)</code></member>
+
+<member><ulink url="&clhs;f_logand.htm"><symbol>lognot</symbol></ulink></member>
+<member><code>cl_object cl_lognot(cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_logand.htm"><symbol>logorc1</symbol></ulink></member>
+<member><code>cl_object cl_logorc1(cl_object integer1, cl_object integer2)</code></member>
+
+<member><ulink url="&clhs;f_logand.htm"><symbol>logorc2</symbol></ulink></member>
+<member><code>cl_object cl_logorc2(cl_object integer1, cl_object integer2)</code></member>
+
+<member><ulink url="&clhs;f_logand.htm"><symbol>logxor</symbol></ulink></member>
+<member><code>cl_object cl_logxor(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_logbtp.htm"><symbol>logbitp</symbol></ulink></member>
+<member><code>cl_object cl_logbitp(cl_object index, cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_logcou.htm"><symbol>logcount</symbol></ulink></member>
+<member><code>cl_object cl_logcount(cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_logtes.htm"><symbol>logtest</symbol></ulink></member>
+<member><code>cl_object cl_logtest(cl_object integer1, cl_object integer2)</code></member>
+
+<member><ulink url="&clhs;f_by_by.htm"><symbol>byte</symbol></ulink></member>
+<member><code>cl_object cl_byte(cl_object size, cl_object position)</code></member>
+
+<member><ulink url="&clhs;f_by_by.htm"><symbol>bytes-size</symbol></ulink></member>
+<member><code>cl_object cl_byte_size(cl_object bytespec)</code></member>
+
+<member><ulink url="&clhs;f_by_by.htm"><symbol>byte-position</symbol></ulink></member>
+<member><code>cl_object cl_byte_position(cl_object bytespec)</code></member>
+
+<member><ulink url="&clhs;f_deposi.htm"><symbol>deposit-field</symbol></ulink></member>
+<member><code>cl_object cl_deposit_field(cl_object newbyte, cl_object bytespec, cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_dpb.htm"><symbol>dpb</symbol></ulink></member>
+<member><code>cl_object cl_dpb(cl_object newbyte, cl_object bytespec, cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_ldb.htm"><symbol>ldb</symbol></ulink></member>
+<member><code>cl_object cl_ldb(cl_object bytespec, cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_ldb_te.htm"><symbol>ldb-test</symbol></ulink></member>
+<member><code>cl_object cl_ldb_test(cl_object bytespec, cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_mask_f.htm"><symbol>mask-field</symbol></ulink></member>
+<member><code>cl_object cl_mask_field(cl_object bytespec, cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_dec_fl.htm"><symbol>decode-float</symbol></ulink></member>
+<member><code>cl_object cl_decode_float(cl_object float)</code></member>
+
+<member><ulink url="&clhs;f_dec_fl.htm"><symbol>scale-float</symbol></ulink></member>
+<member><code>cl_object cl_scale_float(cl_object float, cl_object integer)</code></member>
+
+<member><ulink url="&clhs;f_dec_fl.htm"><symbol>float-radix</symbol></ulink></member>
+<member><code>cl_object cl_float_radix(cl_object float)</code></member>
+
+<member><ulink url="&clhs;f_dec_fl.htm"><symbol>float-sign</symbol></ulink></member>
+<member><code>cl_object cl_float_sign(cl_narg narg, cl_object float1, ...)</code></member>
+
+<member><ulink url="&clhs;f_dec_fl.htm"><symbol>float-digits</symbol></ulink></member>
+<member><code>cl_object cl_float_digits(cl_object float)</code></member>
+
+<member><ulink url="&clhs;f_dec_fl.htm"><symbol>float-precision</symbol></ulink></member>
+<member><code>cl_object cl_float_precision(cl_object float)</code></member>
+
+<member><ulink url="&clhs;f_dec_fl.htm"><symbol>integer-decode-float</symbol></ulink></member>
+<member><code>cl_object cl_integer_decode_float(cl_object float)</code></member>
+
+<member><ulink url="&clhs;f_float.htm"><symbol>float</symbol></ulink></member>
+<member><code>cl_object cl_float(cl_narg narg, cl_object number)</code></member>
+
+<member><ulink url="&clhs;f_floatp.htm"><symbol>floatp</symbol></ulink></member>
+<member><code>cl_object cl_floatp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_arithm.htm"><symbol>arithmetic-error-operands</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_arithm.htm"><symbol>arithmetic-error-operation</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+</simplelist>
+ </refsynopsisdiv>
+ </refentry>
+
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Objects</title>
+<section xml:id="ansi.objects.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_fn_kwd.htm"><symbol>function-keywords</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_ensure.htm"><symbol>ensure-generic-function</symbol></ulink></member>
+<member><code>cl_object cl_ensure_generic_function(cl_narg narg, cl_object function_name, ...)</code></member>
+
+<member><ulink url="&clhs;f_alloca.htm"><symbol>allocate-instance</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_reinit.htm"><symbol>reinitialize-instance</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_shared.htm"><symbol>shared-initialize</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_update.htm"><symbol>update-instance-for-different-class</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_upda_1.htm"><symbol>update-instance-for-redefined-class</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_chg_cl.htm"><symbol>change-class</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_slt_bo.htm"><symbol>slot-boundp</symbol></ulink></member>
+<member><code>cl_object cl_slot_boundp(cl_object instance, cl_object slot_name)</code></member>
+
+<member><ulink url="&clhs;f_slt_ex.htm"><symbol>slot-exists-p</symbol></ulink></member>
+<member><code>cl_object cl_slot_exists_p(cl_object instance, cl_object slot_name)</code></member>
+
+<member><ulink url="&clhs;f_slt_ma.htm"><symbol>slot-makunbound</symbol></ulink></member>
+<member><code>cl_object cl_slot_makunbound(cl_object instance, cl_object slot_name)</code></member>
+
+<member><ulink url="&clhs;f_slt_mi.htm"><symbol>slot-missing</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_slt_un.htm"><symbol>slot-unbound</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_slt_va.htm"><symbol>slot-value</symbol></ulink></member>
+<member><code>cl_object cl_slot_value(cl_object instance, cl_object slot_name)</code></member>
+
+<member><ulink url="&clhs;f_method.htm"><symbol>method-qualifiers</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_no_app.htm"><symbol>no-applicable-method</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_no_nex.htm"><symbol>no-next-method</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_rm_met.htm"><symbol>remove-method</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_mk_ins.htm"><symbol>make-instance</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_mk_i_1.htm"><symbol>make-instances-obsolete</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_mk_ld_.htm"><symbol>make-load-form</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_mk_l_1.htm"><symbol>make-load-form-saving-slots</symbol></ulink></member>
+<member><code>cl_object cl_make_load_form_saving_slots(cl_narg narg, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_find_c.htm"><symbol>find-class</symbol></ulink></member>
+<member><code>cl_object cl_find_class(cl_narg narg, cl_object symbol, ...)</code></member>
+
+<member><ulink url="&clhs;f_comput.htm"><symbol>compute-applicable-methods</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_find_m.htm"><symbol>find-method</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_add_me.htm"><symbol>add-method</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_init_i.htm"><symbol>initialize-instance</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_class_.htm"><symbol>class-name</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_opsetf.htm"><symbol>(setf class-name)</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_clas_1.htm"><symbol>class-of</symbol></ulink></member>
+<member><code>cl_object cl_class_of(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_unboun.htm"><symbol>unbound-slot-instance</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Packages</title>
+<section xml:id="ansi.packages.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_export.htm"><symbol>export</symbol></ulink></member>
+<member><code>cl_object cl_export(cl_narg narg, cl_object symbols_list, ...)</code></member>
+
+<member><ulink url="&clhs;f_find_s.htm"><symbol>find-symbol</symbol></ulink></member>
+<member><code>cl_object cl_find_symbol(cl_narg narg, cl_object string, ...)</code></member>
+
+<member><ulink url="&clhs;f_find_p.htm"><symbol>find-package</symbol></ulink></member>
+<member><code>cl_object cl_find_package(cl_object string)</code></member>
+
+<member><ulink url="&clhs;f_find_a.htm"><symbol>find-all-symbols</symbol></ulink></member>
+<member><code>cl_object cl_find_all_symbols(cl_object string)</code></member>
+
+<member><ulink url="&clhs;f_import.htm"><symbol>import</symbol></ulink></member>
+<member><code>cl_object cl_import(cl_narg narg, cl_object symbols)</code></member>
+
+<member><ulink url="&clhs;f_list_a.htm"><symbol>list-all-packages</symbol></ulink></member>
+<member><code>cl_object cl_list_all_packages(void)</code></member>
+
+<member><ulink url="&clhs;f_rn_pkg.htm"><symbol>rename-package</symbol></ulink></member>
+<member><code>cl_object cl_rename_package(cl_narg narg, cl_object package, cl_object new_name, ...)</code></member>
+
+<member><ulink url="&clhs;f_shadow.htm"><symbol>shadow</symbol></ulink></member>
+<member><code>cl_object cl_shadow(cl_narg narg, cl_object symbol_names)</code></member>
+
+<member><ulink url="&clhs;f_shdw_i.htm"><symbol>shadowing-import</symbol></ulink></member>
+<member><code>cl_object cl_shadowing_import(cl_narg narg, cl_object symbols, ...)</code></member>
+
+<member><ulink url="&clhs;f_del_pk.htm"><symbol>delete-package</symbol></ulink></member>
+<member><code>cl_object cl_delete_package(cl_object package_designator)</code></member>
+
+<member><ulink url="&clhs;f_mk_pkg.htm"><symbol>make-package</symbol></ulink></member>
+<member><code>cl_object cl_make_package(cl_narg narg, cl_object package_name, ...)</code></member>
+
+<member><ulink url="&clhs;f_unexpo.htm"><symbol>unexport</symbol></ulink></member>
+<member><code>cl_object cl_unexport(cl_narg narg, cl_object symbols_list, ...)</code></member>
+
+<member><ulink url="&clhs;f_uninte.htm"><symbol>unintern</symbol></ulink></member>
+<member><code>cl_object cl_unintern(cl_narg narg, cl_object symbol, ...)</code></member>
+
+<member><ulink url="&clhs;m_in_pkg.htm"><symbol>in-package</symbol></ulink></member>
+<member><code>cl_object si_select_package(cl_narg narg, cl_object name)</code></member>
+
+<member><ulink url="&clhs;f_unuse_.htm"><symbol>unuse-package</symbol></ulink></member>
+<member><code>cl_object cl_unuse_package(cl_narg narg, cl_object packages_list)</code></member>
+
+<member><ulink url="&clhs;f_use_pk.htm"><symbol>use-package</symbol></ulink></member>
+<member><code>cl_object cl_use_package(cl_narg narg, cl_object packages_list)</code></member>
+
+<member><ulink url="&clhs;f_intern.htm"><symbol>intern</symbol></ulink></member>
+<member><code>cl_object cl_intern(cl_narg narg, cl_object string, ...)</code></member>
+
+<member><ulink url="&clhs;f_pkg_na.htm"><symbol>package-name</symbol></ulink></member>
+<member><code>cl_object cl_package_name(cl_object package_designator)</code></member>
+
+<member><ulink url="&clhs;f_pkg_ni.htm"><symbol>package-nicknames</symbol></ulink></member>
+<member><code>cl_object cl_package_nicknames(cl_object package_designator)</code></member>
+
+<member><ulink url="&clhs;f_pkg_sh.htm"><symbol>package-shadowing-symbols</symbol></ulink></member>
+<member><code>cl_object cl_package_shadowing_symbols(cl_object package_designator)</code></member>
+
+<member><ulink url="&clhs;f_pkg_us.htm"><symbol>package-use-list</symbol></ulink></member>
+<member><code>cl_object cl_package_use_list(cl_object package_designator)</code></member>
+
+<member><ulink url="&clhs;f_pkg__1.htm"><symbol>package-used-by-list</symbol></ulink></member>
+<member><code>cl_object cl_package_used_by_list(cl_object package_designator)</code></member>
+
+<member><ulink url="&clhs;f_pkgp.htm"><symbol>packagep</symbol></ulink></member>
+<member><code>cl_object cl_packagep(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_pkg_er.htm"><symbol>package-error-package</symbol></ulink></member>
+<member><code>[Only in Common Lisp]</code></member>
+</simplelist>
+ </refsynopsisdiv>
+ </refentry>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Printer</title>
+<section xml:id="ansi.printer.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_cp_ppr.htm"><symbol>copy-pprint-dispatch</symbol></ulink></member>
+<member><code>cl_object cl_copy_pprint_dispatch(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_ppr_di.htm"><symbol>pprint-dispatch</symbol></ulink></member>
+<member><code>cl_object cl_pprint_dispatch(cl_narg narg, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_ppr_fi.htm"><symbol>pprint-fill</symbol></ulink></member>
+<member><code>cl_object cl_pprint_fill(cl_narg narg, cl_object stream, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_ppr_fi.htm"><symbol>pprint-linear</symbol></ulink></member>
+<member><code>cl_object cl_pprint_linear(cl_narg narg, cl_object stream, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_ppr_fi.htm"><symbol>pprint-tabular</symbol></ulink></member>
+<member><code>cl_object cl_pprint_tabular(cl_narg narg, cl_object stream, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_ppr_in.htm"><symbol>pprint-indent</symbol></ulink></member>
+<member><code>cl_object cl_pprint_indent(cl_narg narg, cl_object relative_to, cl_object n, ...)</code></member>
+
+<member><ulink url="&clhs;f_ppr_nl.htm"><symbol>pprint-newline</symbol></ulink></member>
+<member><code>cl_object cl_pprint_newline(cl_narg narg, cl_object kind, ...)</code></member>
+
+<member><ulink url="&clhs;f_ppr_ta.htm"><symbol>pprint-tab</symbol></ulink></member>
+<member><code>cl_object cl_pprint_tab(cl_narg narg, cl_object kind, cl_object colnum, cl_object colinc, ...)</code></member>
+
+<member><ulink url="&clhs;f_pr_obj.htm"><symbol>print-object</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_set_pp.htm"><symbol>set-pprint-dispatch</symbol></ulink></member>
+<member><code>cl_object cl_set_pprint_dispatch(cl_narg narg, cl_object ype_spec, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;f_wr_pr.htm"><symbol>write</symbol></ulink></member>
+<member><code>cl_object cl_write(cl_narg narg, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_wr_pr.htm"><symbol>prin1</symbol></ulink></member>
+<member><code>cl_object cl_prin1(cl_narg narg, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_wr_pr.htm"><symbol>princ</symbol></ulink></member>
+<member><code>cl_object cl_princ(cl_narg narg, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_wr_pr.htm"><symbol>print</symbol></ulink></member>
+<member><code>cl_object cl_print(cl_narg narg, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_wr_pr.htm"><symbol>pprint</symbol></ulink></member>
+<member><code>cl_object cl_pprint(cl_narg narg, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_wr_to_.htm"><symbol>write-to-string</symbol></ulink></member>
+<member><code>cl_object cl_write_to_string(cl_narg narg, cl_object object, ...)</code></member>
+
+<member><ulink url="&clhs;f_wr_to_.htm"><symbol>prin1-to-string</symbol></ulink></member>
+<member><code>cl_object cl_prin1_to_string(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_wr_to_.htm"><symbol>princ-to-string</symbol></ulink></member>
+<member><code>cl_object cl_princ_to_string(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_pr_not.htm"><symbol>print-not-readable-object</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_format.htm"><symbol>format</symbol></ulink></member>
+<member><code>cl_object cl_format(cl_narg narg, cl_object string, ...)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Reader</title>
+<section xml:id="ansi.reader.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_cp_rdt.htm"><symbol>copy-readtable</symbol></ulink></member>
+<member><code>cl_object cl_copy_readtable(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_mk_dis.htm"><symbol>make-dispatch-macro-character</symbol></ulink></member>
+<member><code>cl_object cl_make_dispatch_macro_character(cl_narg narg, cl_object char, ...)</code></member>
+
+<member><ulink url="&clhs;f_rd_rd.htm"><symbol>read</symbol></ulink></member>
+<member><code>cl_object cl_read(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_rd_rd.htm"><symbol>read-preerving-whitespace</symbol></ulink></member>
+<member><code>cl_object cl_read_preserving_whitespace(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_rd_del.htm"><symbol>read-delimited-list</symbol></ulink></member>
+<member><code>cl_object cl_read_delimited_list(cl_narg narg, cl_object char, ...)</code></member>
+
+<member><ulink url="&clhs;f_rd_fro.htm"><symbol>read-from-string</symbol></ulink></member>
+<member><code>cl_object cl_read_from_string(cl_narg narg, cl_object string, ...)</code></member>
+
+<member><ulink url="&clhs;f_rdtabl.htm"><symbol>readtable-case</symbol></ulink></member>
+<member><code>cl_object cl_readtable_case(cl_object readtable)</code></member>
+
+<member><ulink url="&clhs;f_rdta_1.htm"><symbol>readtablep</symbol></ulink></member>
+<member><code>cl_object cl_readtablep(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_set__1.htm"><symbol>get-dispatch-macro-character</symbol></ulink></member>
+<member><code>cl_object cl_get_dispatch_macro_character(cl_narg narg, cl_object disp_char, cl_object sub_char, ...)</code></member>
+
+<member><ulink url="&clhs;f_set__1.htm"><symbol>set-dispatch-macro-character</symbol></ulink></member>
+<member><code>cl_object cl_set_dispatch_macro_character(cl_narg narg, cl_object disp_char, cl_object sub_char, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;f_set_ma.htm"><symbol>get-macro-character</symbol></ulink></member>
+<member><code>cl_object cl_get_macro_character(cl_narg narg, cl_object char, ...)</code></member>
+
+<member><ulink url="&clhs;f_set_ma.htm"><symbol>set-macro-character</symbol></ulink></member>
+<member><code>cl_object cl_set_macro_character(cl_narg narg, cl_object char, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;f_set_sy.htm"><symbol>set-syntax-from-char</symbol></ulink></member>
+<member><code>cl_object cl_set_syntax_from_char(cl_narg narg, cl_object to_char, cl_object from_char, ...)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Conses</title>
+<section xml:id="ansi.sequences.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>Sequences C dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_concat.htm"><symbol>concatenate</symbol></ulink></member>
+<member><code>cl_object cl_concatenate(cl_narg narg, cl_object result_type, ...)</code></member>
+
+<member><ulink url="&clhs;f_cp_seq.htm"><symbol>copy-seq</symbol></ulink></member>
+<member><code>cl_object cl_copy_seq(cl_object sequence)</code></member>
+
+<member><ulink url="&clhs;f_countc.htm"><symbol>count</symbol></ulink></member>
+<member><code>cl_object cl_count(cl_narg narg, cl_object item, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_countc.htm"><symbol>count-if</symbol></ulink></member>
+<member><code>cl_object cl_count_if(cl_narg narg, cl_object predicate, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_countc.htm"><symbol>count-if-not</symbol></ulink></member>
+<member><code>cl_object cl_count_if_not(cl_narg narg, cl_object predicate, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_rm_rm.htm"><symbol>delete</symbol></ulink></member>
+<member><code>cl_object cl_delete(cl_narg narg, cl_object newitem, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_rm_rm.htm"><symbol>delete-if</symbol></ulink></member>
+<member><code>cl_object cl_delete_if(cl_narg narg, cl_object newitem, cl_object test, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_rm_rm.htm"><symbol>delete-if-not</symbol></ulink></member>
+<member><code>cl_object cl_delete_if_not(cl_narg narg, cl_object newitem, cl_object test, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_rm_dup.htm"><symbol>delete-duplicates</symbol></ulink></member>
+<member><code>cl_object cl_delete_duplicates(cl_narg narg, cl_object sequence)</code></member>
+
+<member><ulink url="&clhs;f_elt.htm"><symbol>elt</symbol></ulink></member>
+<member><code>cl_object cl_elt(cl_object sequence, cl_object index)</code></member>
+
+<member><ulink url="&clhs;f_fill.htm"><symbol>fill</symbol></ulink></member>
+<member><code>cl_object cl_fill(cl_narg narg, cl_object sequence, cl_object item, ...)</code></member>
+
+<member><ulink url="&clhs;f_find_.htm"><symbol>find</symbol></ulink></member>
+<member><code>cl_object cl_find(cl_narg narg, cl_object item, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_find_.htm"><symbol>find-if</symbol></ulink></member>
+<member><code>cl_object cl_find_if(cl_narg narg, cl_object predicate, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_find_.htm"><symbol>find-if-not</symbol></ulink></member>
+<member><code>cl_object cl_find_if_not(cl_narg narg, cl_object predicate, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_mk_seq.htm"><symbol>make-sequence</symbol></ulink></member>
+<member><code>cl_object cl_make_sequence(cl_narg narg, cl_object result_type, cl_object size, ...)</code></member>
+
+<member><ulink url="&clhs;f_map.htm"><symbol>map</symbol></ulink></member>
+<member><code>cl_object cl_map(cl_narg narg, cl_object result_type, cl_object function)</code></member>
+
+<member><ulink url="&clhs;f_map_in.htm"><symbol>map-into</symbol></ulink></member>
+<member><code>cl_object cl_map_into(cl_narg narg, cl_object result_sequence, cl_object function, ...)</code></member>
+
+<member><ulink url="&clhs;f_merge.htm"><symbol>merge</symbol></ulink></member>
+<member><code>cl_object cl_merge(cl_narg narg, cl_object result_type, cl_object sequence1, cl_object sequence2, ...)</code></member>
+
+<member><ulink url="&clhs;f_mismat.htm"><symbol>mismatch</symbol></ulink></member>
+<member><code>cl_object cl_mismatch(cl_narg narg, cl_object sequence1, cl_object sequence2)</code></member>
+
+<member><ulink url="&clhs;f_revers.htm"><symbol>nreverse</symbol></ulink></member>
+<member><code>cl_object cl_nreverse(cl_object sequence)</code></member>
+
+<member><ulink url="&clhs;f_sbs_s.htm"><symbol>nsubstitute</symbol></ulink></member>
+<member><code>cl_object cl_nsubstitute(cl_narg narg, cl_object newitem, cl_object olditem, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_sbs_s.htm"><symbol>nsubstitute-if</symbol></ulink></member>
+<member><code>cl_object cl_nsubstitute_if(cl_narg narg, cl_object newitem, cl_object predicate, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_sbs_s.htm"><symbol>nsubstitute-if-not</symbol></ulink></member>
+<member><code>cl_object cl_nsubstitute_if_not(cl_narg narg, cl_object newitem, cl_object predicate, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_pos_p.htm"><symbol>position</symbol></ulink></member>
+<member><code>cl_object cl_position(cl_narg narg, cl_object item, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_pos_p.htm"><symbol>position-if</symbol></ulink></member>
+<member><code>cl_object cl_pos_pif(cl_narg narg, cl_object predicate, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_pos_p.htm"><symbol>position-if-not</symbol></ulink></member>
+<member><code>cl_object cl_pos_pif_not(cl_narg narg, cl_object predicate, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_reduce.htm"><symbol>reduce</symbol></ulink></member>
+<member><code>cl_object cl_reduce(cl_narg narg, cl_object function, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_rm_rm.htm"><symbol>remove</symbol></ulink></member>
+<member><code>cl_object cl_remove(cl_narg narg, cl_object newitem, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_rm_rm.htm"><symbol>remove-if</symbol></ulink></member>
+<member><code>cl_object cl_remove_if(cl_narg narg, cl_object newitem, cl_object test, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_rm_rm.htm"><symbol>remove-if-not</symbol></ulink></member>
+<member><code>cl_object cl_remove_if_not(cl_narg narg, cl_object newitem, cl_object test, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_rm_dup.htm"><symbol>remove-duplicates</symbol></ulink></member>
+<member><code>cl_object cl_remove_duplicates(cl_narg narg, cl_object sequence)</code></member>
+
+<member><ulink url="&clhs;f_replac.htm"><symbol>replace</symbol></ulink></member>
+<member><code>cl_object cl_replace(cl_narg narg, cl_object sequence1, cl_object sequence2)</code></member>
+
+<member><ulink url="&clhs;f_revers.htm"><symbol>reverse</symbol></ulink></member>
+<member><code>cl_object cl_reverse(cl_object sequence)</code></member>
+
+<member><ulink url="&clhs;f_search.htm"><symbol>search</symbol></ulink></member>
+<member><code>cl_object cl_search(cl_narg narg, cl_object sequence1, cl_object sequence2)</code></member>
+
+<member><ulink url="&clhs;f_sort_.htm"><symbol>sort</symbol></ulink></member>
+<member><code>cl_object cl_sort(cl_narg narg, cl_object sequence, cl_object predicate, ...)</code></member>
+
+<member><ulink url="&clhs;f_sort_.htm"><symbol>stable-sort</symbol></ulink></member>
+<member><code>cl_object cl_stable_sort(cl_narg narg, cl_object sequence, cl_object predicate, ...)</code></member>
+
+<member><ulink url="&clhs;f_subseq.htm"><symbol>subseq</symbol></ulink></member>
+<member><code>cl_object cl_subseq(cl_narg narg, cl_object sequence, cl_object start)</code></member>
+
+<member><ulink url="&clhs;f_sbs_s.htm"><symbol>substitute</symbol></ulink></member>
+<member><code>cl_object cl_substitute(cl_narg narg, cl_object newitem, cl_object olditem, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_sbs_s.htm"><symbol>substitute-if</symbol></ulink></member>
+<member><code>cl_object cl_substitute_if(cl_narg narg, cl_object newitem, cl_object predicate, cl_object sequence, ...)</code></member>
+
+<member><ulink url="&clhs;f_sbs_s.htm"><symbol>substitute-if-not</symbol></ulink></member>
+<member><code>cl_object cl_substitute_if_not(cl_narg narg, cl_object newitem, cl_object predicate, cl_object sequence, ...)</code></member>
+
+</simplelist>
+ </refsynopsisdiv>
+ </refentry>
+</section>
+</chapter>
+</book>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Streams</title>
+<section xml:id="ansi.streams.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>Streams C dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_broadc.htm"><symbol>broadcast-stream-streams</symbol></ulink></member>
+<member><code>cl_object cl_broadcast_stream_streams(cl_object broadcast_stream)</code></member>
+
+<member><ulink url="&clhs;f_clear_.htm"><symbol>clear-input</symbol></ulink></member>
+<member><code>cl_object cl_clear_input(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_finish.htm"><symbol>clear-output</symbol></ulink></member>
+<member><code>cl_object cl_clear_outputt(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_close.htm"><symbol>close</symbol></ulink></member>
+<member><code>cl_object cl_close(cl_narg narg, cl_object stream, ...)</code></member>
+
+<member><ulink url="&clhs;f_conc_1.htm"><symbol>concatenated-stream-streams</symbol></ulink></member>
+<member><code>cl_object cl_concatenated_stream_streams(cl_object concatenated_stream)</code></member>
+
+<member><ulink url="&clhs;f_echo_s.htm"><symbol>echo-stream-input-stream</symbol></ulink></member>
+<member><code>cl_object cl_echo_stream_input_stream(cl_object echo_stream)</code></member>
+
+<member><ulink url="&clhs;f_echo_s.htm"><symbol>echo-stream-output-stream</symbol></ulink></member>
+<member><code>cl_object cl_echo_stream_output_stream(cl_object echo_stream)</code></member>
+
+<member><ulink url="&clhs;f_file_l.htm"><symbol>file-length</symbol></ulink></member>
+<member><code>cl_object cl_file_length(cl_object stream)</code></member>
+
+<member><ulink url="&clhs;f_file_p.htm"><symbol>file-position</symbol></ulink></member>
+<member><code>cl_object cl_file_position(cl_object stream)</code></member>
+
+<member><ulink url="&clhs;f_file_s.htm"><symbol>file-string-length</symbol></ulink></member>
+<member><code>cl_object cl_file_string_length(cl_object stream, cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_finish.htm"><symbol>finish-output</symbol></ulink></member>
+<member><code>cl_object cl_finish_outputt(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_finish.htm"><symbol>force-output</symbol></ulink></member>
+<member><code>cl_object cl_force_outputt(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_terpri.htm"><symbol>fresh-line</symbol></ulink></member>
+<member><code>cl_object cl_fresh_line(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_get_ou.htm"><symbol>get-output-stream-string</symbol></ulink></member>
+<member><code>cl_object cl_get_output_stream_string(cl_object string_output_stream)</code></member>
+
+<member><ulink url="&clhs;f_in_stm.htm"><symbol>input-stream-p</symbol></ulink></member>
+<member><code>cl_object cl_input_stream_p(cl_object stream)</code></member>
+
+<member><ulink url="&clhs;f_intera.htm"><symbol>interactive-stream-p</symbol></ulink></member>
+<member><code>cl_object cl_interactive_stream_p(cl_object stream)</code></member>
+
+<member><ulink url="&clhs;f_listen.htm"><symbol>listen</symbol></ulink></member>
+<member><code>cl_object cl_listen(cl_narg narg, cl_object stream, ...)</code></member>
+
+<member><ulink url="&clhs;f_mk_bro.htm"><symbol>make-broadcast-stream</symbol></ulink></member>
+<member><code>cl_object cl_make_broadcast_stream(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_mk_con.htm"><symbol>make-concatenated-stream</symbol></ulink></member>
+<member><code>cl_object cl_make_concatenated_stream(cl_narg narg, ....)</code></member>
+
+<member><ulink url="&clhs;f_mk_ech.htm"><symbol>make-echo-stream</symbol></ulink></member>
+<member><code>cl_object cl_make_echo_stream(cl_object input, cl_object output)</code></member>
+
+<member><ulink url="&clhs;f_mk_s_1.htm"><symbol>make-string-input-stream</symbol></ulink></member>
+<member><code>cl_object cl_make_string_input_stream(cl_narg narg, cl_object string, ...)</code></member>
+
+<member><ulink url="&clhs;f_mk_s_2.htm"><symbol>make-string-output-stream</symbol></ulink></member>
+<member><code>cl_object cl_make_string_output_stream(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_mk_two.htm"><symbol>make-two-way-stream</symbol></ulink></member>
+<member><code>cl_object cl_make_two_way_stream(cl_object input, cl_object output)</code></member>
+
+<member><ulink url="&clhs;f_mk_syn.htm"><symbol>make-synonym-stream</symbol></ulink></member>
+<member><code>cl_object cl_make_synonym_stream(cl_object symbol)</code></member>
+
+<member><ulink url="&clhs;f_open.htm"><symbol>open</symbol></ulink></member>
+<member><code>cl_object cl_open(cl_narg narg, cl_object filespec, ...)</code></member>
+
+<member><ulink url="&clhs;f_open_s.htm"><symbol>open-stream-p</symbol></ulink></member>
+<member><code>cl_object cl_open_stream_p(cl_object stream)</code></member>
+
+<member><ulink url="&clhs;f_in_stm.htm"><symbol>output-stream-p</symbol></ulink></member>
+<member><code>cl_object cl_output_stream_p(cl_object stream)</code></member>
+
+<member><ulink url="&clhs;f_peek_c.htm"><symbol>peek-char</symbol></ulink></member>
+<member><code>cl_object cl_peek_char(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_rd_by.htm"><symbol>read-byte</symbol></ulink></member>
+<member><code>cl_object cl_read_byte(cl_narg narg, cl_object stream, ...)</code></member>
+
+<member><ulink url="&clhs;f_rd_cha.htm"><symbol>read-char</symbol></ulink></member>
+<member><code>cl_object cl_read_char(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_rd_c_1.htm"><symbol>read-char-no-hang</symbol></ulink></member>
+<member><code>cl_object cl_read_char_no_hang(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_rd_lin.htm"><symbol>read-line</symbol></ulink></member>
+<member><code>cl_object cl_read_line(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_rd_seq.htm"><symbol>read-sequence</symbol></ulink></member>
+<member><code>cl_object cl_read_sequence(cl_narg narg, cl_object sequence, cl_object stream)</code></member>
+
+<member><ulink url="&clhs;f_stm_el.htm"><symbol>stream-element-type</symbol></ulink></member>
+<member><code>cl_object cl_stream_element_type(cl_object stream)</code></member>
+
+<member><ulink url="&clhs;f_stm_er.htm"><symbol>stream-error-stream</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_stm_ex.htm"><symbol>stream-external-format</symbol></ulink></member>
+<member><code>cl_object cl_stream_external_format(cl_object stream)</code></member>
+
+<member><ulink url="&clhs;f_stmp.htm"><symbol>streamp</symbol></ulink></member>
+<member><code>cl_object cl_streamp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_syn_st.htm"><symbol>synonym-stream-symbol</symbol></ulink></member>
+<member><code>cl_object cl_synonym_stream_symbol(cl_object synonym_stream)</code></member>
+
+<member><ulink url="&clhs;f_terpri.htm"><symbol>terpri</symbol></ulink></member>
+<member><code>cl_object cl_terpri(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_two_wa.htm"><symbol>two-way-stream-input-stream</symbol></ulink></member>
+<member><code>cl_object cl_two_way_stream_input_stream(cl_object two_way_stream)</code></member>
+
+<member><ulink url="&clhs;f_two_wa.htm"><symbol>two-way-stream-output-stream</symbol></ulink></member>
+<member><code>cl_object cl_two_way_stream_output_stream(cl_object two_way_stream)</code></member>
+
+<member><ulink url="&clhs;f_unrd_c.htm"><symbol>unread-char</symbol></ulink></member>
+<member><code>cl_object cl_unread_char(cl_narg narg, cl_object character, ...)</code></member>
+
+<member><ulink url="&clhs;f_wr_by.htm"><symbol>write-byte</symbol></ulink></member>
+<member><code>cl_object cl_write_byte(cl_object byte, cl_object stream)</code></member>
+
+<member><ulink url="&clhs;f_wr_cha.htm"><symbol>write-char</symbol></ulink></member>
+<member><code>cl_object cl_write_char(cl_narg narg, cl_object character, ...)</code></member>
+
+<member><ulink url="&clhs;f_wr_stg.htm"><symbol>write-line</symbol></ulink></member>
+<member><code>cl_object cl_write_line(cl_narg narg, cl_object string)</code></member>
+
+<member><ulink url="&clhs;f_wr_stg.htm"><symbol>write-string</symbol></ulink></member>
+<member><code>cl_object cl_write_string(cl_narg narg, cl_object string)</code></member>
+
+<member><ulink url="&clhs;f_wr_seq.htm"><symbol>write-sequence</symbol></ulink></member>
+<member><code>cl_object cl_write_sequence(cl_narg narg, cl_object sequence, cl_object stream)</code></member>
+
+<member><ulink url="&clhs;f_y_or_n.htm"><symbol>y-or-n-p</symbol></ulink></member>
+<member><code>cl_object cl_y_or_n_p(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_y_or_n.htm"><symbol>yes-or-no-p</symbol></ulink></member>
+<member><code>cl_object cl_yes_or_no_p(cl_narg narg, ...)</code></member>
+
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Strings and compilation</title>
+<section xml:id="ansi.strings.c-dict">
+<title>C Reference</title>
+
+ <refentry xml:id="ansi.strings.c-types">
+ <refnamediv>
+ <refname>Base string constructors</refname>
+ <refpurpose>Building strings for C data</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_alloc_adjustable_base_string</function></funcdef>
+ <paramdef><type>cl_index</type> <parameter>length</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_alloc_adjustable_simple_string</function></funcdef>
+ <paramdef><type>cl_index</type> <parameter>length</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_simple_base_string</function></funcdef>
+ <paramdef><type>ecl_base_char*</type> <parameter>data</parameter></paramdef>
+ <paramdef><type>cl_index</type> <parameter>length</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_constant_base_string</function></funcdef>
+ <paramdef><type>ecl_base_char*</type> <parameter>data</parameter></paramdef>
+ <paramdef><type>cl_index</type> <parameter>length</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>These are different ways to create a base string, which is a string that holds a small subset of characters, the <type>base-char</type>, with codes ranging from 0 to 255.</para>
+
+ <para><function>ecl_alloc_simple_base_string</function> creates an empty string with that much space for characters and a fixed lenght. The string does not have a fill pointer and cannot be resized, and the initial data is unspecified</para>
+
+ <para><function>ecl_alloc_adjustable_base_string</function> is similar to the previous function, but creates an adjustable string with a fill pointer. This means that the lenght of the string can be changed and the string itself can be resized to accomodate more data.</para>
+
+ <para>The other constructors create strings but use some preexisting data. <function>ecl_make_simple_base_string</function> creates a string copying the data that the user supplies, and using freshly allocated memory. <function>ecl_make_constant_base_string</function> on the other hand, does not allocate memory, but simply uses the supplied pointer as buffer for the string. This last function should be used with care, ensuring that the supplied buffer is not deallocated.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>String accessors</refname>
+ <refpurpose>Reading and writing characters into a string</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>ecl_character <function>ecl_char</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>string</parameter></paramdef>
+ <paramdef><type>cl_index</type> <parameter>ndx</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>ecl_character <function>ecl_char_set</function></funcdef>
+ <paramdef><type>cl_object</type> <parameter>string</parameter></paramdef>
+ <paramdef><type>cl_index</type> <parameter>ndx</parameter></paramdef>
+ <paramdef><type>ecl_character</type> <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Access to string information should be done using these two functions. The first one implements the equivalent of the <symbol>CHAR</symbol> function from Common Lisp, returning the character that is at position <replaceable>ndx</replaceable> in the string <replaceable>s</replaceable>.</para>
+
+ <para>The counterpart of the previous function is <function>ecl_char_set</function>, which implements <symbol>(SETF CHAR)</symbol> and stores character <replaceable>c</replaceable> at the position <replaceable>ndx</replaceable> in the given string.</para>
+
+ <para>Both functions check the type of their arguments and verify that the indices do not exceed the string boundaries. Otherwise they signal a <type>serious-condition</type>.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>Strings C dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_smp_st.htm"><symbol>simple-string-p</symbol></ulink></member>
+<member><code>cl_object cl_simple_string_p(cl_object string)</code></member>
+
+<member><ulink url="&clhs;f_char_.htm"><symbol>char</symbol></ulink></member>
+<member><code>cl_object cl_char(cl_object string, cl_object index)</code></member>
+
+<member><ulink url="&clhs;f_char_.htm"><symbol>schar</symbol></ulink></member>
+<member><code>cl_object cl_schar(cl_object string, cl_object index)</code></member>
+
+<member><ulink url="&clhs;f_string.htm"><symbol>string</symbol></ulink></member>
+<member><code>cl_object cl_string(cl_object x)</code></member>
+
+<member><ulink url="&clhs;f_stg_up.htm"><symbol>string-upcase</symbol></ulink></member>
+<member><code>cl_object cl_string_upcase(cl_narg narg, cl_obejct string, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_up.htm"><symbol>string-downcase</symbol></ulink></member>
+<member><code>cl_object cl_string_downcase(cl_narg narg, cl_obejct string, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_up.htm"><symbol>string-capitalize</symbol></ulink></member>
+<member><code>cl_object cl_string_capitalize(cl_narg narg, cl_obejct string, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_up.htm"><symbol>nstring-upcase</symbol></ulink></member>
+<member><code>cl_object cl_nstring_upcase(cl_narg narg, cl_obejct string, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_up.htm"><symbol>nstring-downcase</symbol></ulink></member>
+<member><code>cl_object cl_nstring_downcase(cl_narg narg, cl_obejct string, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_up.htm"><symbol>nstring-capitalize</symbol></ulink></member>
+<member><code>cl_object cl_nstring_capitalize(cl_narg narg, cl_obejct string, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string-trim</symbol></ulink></member>
+<member><code>cl_object cl_string_trim(cl_object character_bag, cl_object string)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string-left-trim</symbol></ulink></member>
+<member><code>cl_object cl_string_left_trim(cl_object character_bag, cl_object string)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string-right-trim</symbol></ulink></member>
+<member><code>cl_object cl_string_right_trim(cl_object character_bag, cl_object string)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string</symbol></ulink></member>
+<member><code>cl_object cl_string(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string=</symbol></ulink></member>
+<member><code>cl_object cl_stringE(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string/=</symbol></ulink></member>
+<member><code>cl_object cl_stringNE(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string<</symbol></ulink></member>
+<member><code>cl_object cl_stringL(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string></symbol></ulink></member>
+<member><code>cl_object cl_stringG(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string<=</symbol></ulink></member>
+<member><code>cl_object cl_stringLE(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string>=</symbol></ulink></member>
+<member><code>cl_object cl_stringGE(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string-equal</symbol></ulink></member>
+<member><code>cl_object cl_string_equal(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string-not-equal</symbol></ulink></member>
+<member><code>cl_object cl_string_not_equal(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string-lessp</symbol></ulink></member>
+<member><code>cl_object cl_string_lessp(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string-greaterp</symbol></ulink></member>
+<member><code>cl_object cl_string_greaterp(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string-not-greaterp</symbol></ulink></member>
+<member><code>cl_object cl_string_not_greaterp(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stg_tr.htm"><symbol>string-not-lessp</symbol></ulink></member>
+<member><code>cl_object cl_string_not_lessp(cl_narg narg, cl_object string1, cl_object string2, ...)</code></member>
+
+<member><ulink url="&clhs;f_stgp.htm"><symbol>stringp</symbol></ulink></member>
+<member><code>cl_object cl_stringp(cl_object x)</code></member>
+
+<member><ulink url="&clhs;f_mk_stg.htm"><symbol>make-string</symbol></ulink></member>
+<member><code>cl_object cl_make_string(cl_narg narg, cl_object size, ...)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Structures</title>
+<section xml:id="ansi.structures.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_cp_stu.htm"><symbol>copy-structure</symbol></ulink></member>
+<member><code>cl_object cl_copy_structure(cl_object structure)</code></member>
+
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Symbols and compilation</title>
+<section xml:id="ansi.symbols.c-dict">
+<title>C Reference</title>
+<toc/>
+ <refentry>
+ <refnamediv>
+ <refname><function>ecl_make_keyword</function></refname>
+ <refpurpose>Find a lisp keyword</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_keyword</function></funcdef>
+ <paramdef><type>char *</type> <parameter>name</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Many Lisp functions take keyword arguments. When invoking a function with keyword arguments we need keywords, which are a kind of symbols that live in the <literal>KEYWORD</literal> package. This function does the task of finding or creating those keywords from C strings.</para>
+ <itemizedlist>
+ <listitem><para>It is usually safe to store the resulting pointer, because keywords are always referenced by their package and will not be garbage collected (unless of course, you decide to delete it).</para></listitem>
+ <listitem><para>Remember that the case of the string is significant. <code>ecl_make_keyword("TO")</code> with return <literal>:TO</literal>, while <code>ecl_make_keyword("to")</code> returns a completely different keywod, <literal>:|to|</literal>. In short, you usually want to use uppercase.</para></listitem>
+ </itemizedlist>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>The following example converts a section of a string to uppercase characters:</para>
+<programlisting>
+cl_object start = ecl_make_keyword("START");
+cl_object end = ecl_make_keyword("END");
+...
+sup = cl_string_upcase(4, s, start, ecl_make_fixnum(2),
+ end, ecl_make_fixnum(6));
+...
+</programlisting>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname><function>ecl_make_symbol</function></refname>
+ <refpurpose>Find a lisp symbol</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcdef>cl_object <function>ecl_make_symbol</function></funcdef>
+ <paramdef><type>const char *</type> <parameter>name</parameter></paramdef>
+ <paramdef><type>const char *</type> <parameter>package_name</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This function finds or create a symbol in the given package. First of all, it tries to find the package named by <replaceable>package_name</replaceable>. If it does not exist, an error is signaled. Then, a symbol with the suppled <replaceable>name</replaceable> is searched in the given package. If the symbol exists, it is returned. If it does not exist, using <function>INTERN</function>.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_boundp.htm"><symbol>boundp</symbol></ulink></member>
+<member><code>cl_object cl_boundp(cl_object symbolp)</code></member>
+
+<member><ulink url="&clhs;f_cp_sym.htm"><symbol>copy-symbol</symbol></ulink></member>
+<member><code>cl_object cl_copy_symbol(cl_narg narg, cl_object symbol, ...)</code></member>
+
+<member><ulink url="&clhs;f_get.htm"><symbol>get</symbol></ulink></member>
+<member><code>cl_object cl_get(cl_object symbol, cl_object indicator)</code></member>
+
+<member><ulink url="&clhs;f_gensym.htm"><symbol>gensym</symbol></ulink></member>
+<member><code>cl_object cl_gensym(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_gentem.htm"><symbol>gentemp</symbol></ulink></member>
+<member><code>cl_object cl_gentemp(cl_narg narg, ...)</code></member>
+
+<member><ulink url="&clhs;f_kwdp.htm"><symbol>keywordp</symbol></ulink></member>
+<member><code>cl_object cl_keywordp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_mk_sym.htm"><symbol>make-symbol</symbol></ulink></member>
+<member><code>cl_object cl_make_symbol(cl_object name)</code></member>
+
+<member><ulink url="&clhs;f_makunb.htm"><symbol>makunbound</symbol></ulink></member>
+<member><code>cl_object cl_makunbound(cl_object makunbound)</code></member>
+
+<member><ulink url="&clhs;f_rempro.htm"><symbol>remprop</symbol></ulink></member>
+<member><code>cl_object cl_remprop(cl_object symbol, cl_object indicator)</code></member>
+
+<member><ulink url="&clhs;f_set.htm"><symbol>set</symbol></ulink></member>
+<member><code>cl_object cl_set(cl_object symbol, cl_object value)</code></member>
+
+<member><ulink url="&clhs;f_symbol.htm"><symbol>symbolp</symbol></ulink></member>
+<member><code>cl_object cl_symbolp(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_symb_1.htm"><symbol>symbol-function</symbol></ulink></member>
+<member><code>cl_object cl_symbol_function(cl_object symbol)</code></member>
+
+<member><ulink url="&clhs;f_symb_2.htm"><symbol>symbol-name</symbol></ulink></member>
+<member><code>cl_object cl_symbol_name(cl_object symbol)</code></member>
+
+<member><ulink url="&clhs;f_symb_3.htm"><symbol>symbol-package</symbol></ulink></member>
+<member><code>cl_object cl_symbol_package(cl_object symbol)</code></member>
+
+<member><ulink url="&clhs;f_symb_4.htm"><symbol>symbol-plist</symbol></ulink></member>
+<member><code>cl_object cl_symbol_plist(cl_object symbol)</code></member>
+
+<member><ulink url="&clhs;f_symb_5.htm"><symbol>symbol-value</symbol></ulink></member>
+<member><code>cl_object cl_symbol_value(cl_object symbol)</code></member>
+
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>System Construction</title>
+<section xml:id="ansi.system-construction.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_cmp_fi.htm"><symbol>compile-file</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_cmp__1.htm"><symbol>compile-file-pathname</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_load.htm"><symbol>load</symbol></ulink></member>
+<member><code>cl_object cl_load()</code></member>
+
+<member><ulink url="&clhs;f_provid.htm"><symbol>provide</symbol></ulink></member>
+<member><code>cl_object cl_provide(cl_object module_name)</code></member>
+
+<member><ulink url="&clhs;f_provid.htm"><symbol>require</symbol></ulink></member>
+<member><code>cl_object cl_require(cl_narg narg, cl_object module_name, ...)</code></member>
+</simplelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Types and classes</title>
+<section xml:id="ansi.types-and-classes.c-dict">
+<title>C Reference</title>
+ <refentry>
+ <refnamediv>
+ <refname>ANSI Dictionary</refname>
+ <refpurpose>&ANSI-C-Dict;</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<simplelist columns="2" type="horiz">
+<member>Lisp symbol</member>
+<member>C function</member>
+
+<member><ulink url="&clhs;f_coerce.htm"><symbol>coerce</symbol></ulink></member>
+<member><code>cl_object cl_coerce(cl_object object, cl_object result_type)</code></member>
+
+<member><ulink url="&clhs;f_subtpp.htm"><symbol>subtypep</symbol></ulink></member>
+<member><code>cl_object cl_subtypep(cl_narg narg, cl_object type1, cl_object type2, ...)</code></member>
+
+<member><ulink url="&clhs;f_tp_of.htm"><symbol>type-of</symbol></ulink></member>
+<member><code>cl_object cl_type_of(cl_object object)</code></member>
+
+<member><ulink url="&clhs;f_typep.htm"><symbol>typep</symbol></ulink></member>
+<member><code>cl_object cl_typep(cl_narg narg, cl_object object, cl_object type_specifier, ...)</code></member>
+
+<member><ulink url="&clhs;f_tp_err.htm"><symbol>type-error-datum</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+
+<member><ulink url="&clhs;f_tp_err.htm"><symbol>type-error-expected-type</symbol></ulink></member>
+<member><code>&OCL;</code></member>
+</simplelist>
+ </refsynopsisdiv>
+ </refentry>
+</section>
+</chapter>
+</book>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Embedding</title>
+<section xml:id="ext.embed.dict">
+<title>Embedding Reference</title>
+
+<!-- ====================================================================== -->
+<!-- CL_CATCH_ALL -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.embed.cl_catch_all">
+ <refnamediv>
+ <refname><function>CL_CATCH_ALL</function></refname>
+ <refpurpose>Create a protected region.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>C Macro</title>
+<programlisting>
+ cl_env_ptr env = ecl_process_env();
+ CL_CATCH_ALL_BEGIN(env) {
+ /*
+ * Code that is protected. Uncaught lisp conditions, THROW,
+ * signals such as SIGSEGV and SIGBUS may cause jump to
+ * this region.
+ */
+ } CL_CATCH_ALL_IF_CAUGHT {
+ /*
+ * If the exception, lisp condition or other control transfer
+ * is caught, this code is executed.
+ */
+ } CL_CATCH_ALL_END
+ /*
+ * In all cases we exit here.
+ */
+</programlisting>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This is a set of three macros that create an
+ <function>UNWIND-PROTECT</function> region that prevents any nonlocal transfer
+ of control to outer loops. In the Lisp speak, the previous code is
+ equivalent to</para>
+<programlisting>
+(block nil
+ (unwind-protect
+ (progn
+ ;; Code that is protected
+ )
+ (return nil)))
+</programlisting>
+
+ <para>As explained in <xref linkend="ref.embed.cl_unwind_protect" xrefstyle="select: label"/>,it is normally advisable to set up an unwind-protect frame to avoid the embedded lisp code to perform arbitary transfers of control.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><link linkend="ref.embed.cl_unwind_protect"><function>cl_unwind_protect</function></link></para>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- CL_UNWIND_PROTECT -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.embed.cl_unwind_protect">
+ <refnamediv>
+ <refname><function>CL_UNWIND_PROTECT</function></refname>
+ <refpurpose>Create a protected region.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>C Macro</title>
+<programlisting>
+ cl_env_ptr env = ecl_process_env();
+ CL_UNWIND_PROTECT_BEGIN(env) {
+ /*
+ * Code that is protected. Uncaught lisp conditions, THROW,
+ * signals such as SIGSEGV and SIGBUS may cause jump to
+ * this region.
+ */
+ } CL_UNWIND_PROTECT_EXIT {
+ /*
+ * If the exception, lisp condition or other control transfer
+ * is caught, this code is executed. After this code, the
+ * process will jump to the original destination of the
+ * THROW, GOTO or other control statement that was interrupted.
+ */
+ } CL_UNWIND_PROTECT_END
+ /*
+ * We only exit here if NO nonlocal jump was interrupted.
+ */
+</programlisting>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>When embedding &ECL; it is normally advisable to set up an
+ unwind-protect frame to avoid the embedded lisp code to perform arbitary
+ transfers of control. Furthermore, the unwind protect form will be
+ used in at least in the following ocasions:</para>
+ <itemizedlist>
+ <listitem>
+ <para>In a normal program exit, caused by <function>ext:quit</function>,
+ &ECL; unwinds up to the outermost frame, which may be an <xref
+ linkend="ref.embed.cl_catch_all"/> or <xref
+ linkend="ref.embed.cl_unwind_protect"/> macro.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Besides this, normal mechanisms for exit, such as
+ <function>ext:quit</function>, and uncaught exceptions, such as serious
+ signals (<xref linkend="ext.signals.synchronous"/>), are best handled using
+ unwind-protect blocks.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ref.embed.cl_catch_all"/></para>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- cl_boot() -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.embed.cl_boot">
+ <refnamediv>
+ <refname><function>cl_boot</function></refname>
+ <refpurpose>Setup the lisp environment.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcprototype>
+ <funcdef>int <function>cl_boot</function></funcdef>
+ <paramdef>int <parameter>argc</parameter></paramdef>
+ <paramdef>char **<parameter>argv</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>argc</replaceable></term>
+ <listitem><para>An integer with the number of arguments to this program.</para></listitem>
+ <term><replaceable>argv</replaceable></term>
+ <listitem><para>A vector of strings with the arguments to this program.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This function must be called before any other function from the &ECL;
+ library, including the creation of any lisp object or evaluating any lisp code.
+ The only exception are <xref linkend="ref.embed.ecl_set_option"/>
+ and <xref linkend="ref.embed.ecl_get_option"/>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- cl_shutdown() -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.embed.cl_shutdown">
+ <refnamediv>
+ <refname><function>cl_shutdown</function></refname>
+ <refpurpose>Close the lisp environment.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcprototype>
+ <funcdef>int <function>cl_shutdown</function></funcdef>
+ <paramdef>void</paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This function must be called before exiting a program that uses the &ECL;
+ environment. It performs some cleaning, including the execution of any
+ finalizers, unloading shared libraries and deleting temporary files that were
+ created by the compiler.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- ecl_set_option() -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.embed.ecl_set_option">
+ <refnamediv>
+ <refname><function>ecl_set_option</function></refname>
+ <refpurpose>Set a boot option.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcprototype>
+ <funcdef>void <function>ecl_set_option</function></funcdef>
+ <paramdef>int <parameter>option</parameter></paramdef>
+ <paramdef>cl_fixnum <parameter>value</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>option</replaceable></term>
+ <listitem><para>An integer from <xref linkend="table.boot_options"/>.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>value</replaceable></term>
+ <listitem><para>A <type>cl_index</type> value for this option.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This functions sets the value of different options that have
+ to be customized <emphasis>before</emphasis> &ECL; boots. The table
+ of options and default values [<xref linkend="table.boot_options"/>]
+ shows that some of them are boolean, and some of them are unsigned
+ integers.</para>
+
+ <para>We distinguish three sets of values. The first set determines
+ whether &ECL; handles certain exceptions, such as access to forbidden
+ regions of memory, interrupts via <keycombo>Ctrl-C</keycombo>, floating point
+ exceptions, etc.</para>
+
+ <para>The second set is related to the sizes of different
+ stacks. Currently &ECL; uses four stacks: a bind stack for keeping
+ assignments to special variables; a frame stack for implementing
+ blocks, tagbodys and catch points; an interpreter stack for
+ evaluating bytecodes, and finally the machine or C stack, of the
+ computer we run in. We can set the expected size of these stacks,
+ together with the size of a safety area which, if penetrated, will
+ lead to the generation of a correctable error.</para>
+
+ <table xml:id="table.boot_options">
+ <title>Boot options for embedded &ECL;</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Name (<constant>ECL_OPT_*</constant>)</entry>
+ <entry>Type</entry>
+ <entry>Default</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><constant>INCREMENTAL_GC</constant></entry>
+ <entry><type>boolean</type></entry>
+ <entry><constant>TRUE</constant></entry>
+ <entry>Activate generational garbage collector.</entry>
+ </row>
+ <row>
+ <entry><constant>TRAP_SIGSEGV</constant></entry>
+ <entry><type>boolean</type></entry>
+ <entry><constant>TRUE</constant></entry>
+ <entry>Capture SIGSEGV signals.</entry>
+ </row>
+ <row>
+ <entry><constant>TRAP_SIGFPE</constant></entry>
+ <entry><type>boolean</type></entry>
+ <entry><constant>TRUE</constant></entry>
+ <entry>Capture floating point exceptions.</entry>
+ </row>
+ <row>
+ <entry><constant>TRAP_SIGINT</constant></entry>
+ <entry><type>boolean</type></entry>
+ <entry><constant>TRUE</constant></entry>
+ <entry>Capture user interrupts.</entry>
+ </row>
+ <row>
+ <entry><constant>TRAP_SIGILL</constant></entry>
+ <entry><type>boolean</type></entry>
+ <entry><constant>TRUE</constant></entry>
+ <entry>Capture SIGILL exception.</entry>
+ </row>
+ <row>
+ <entry><constant>TRAP_INTERRUPT_SIGNAL</constant></entry>
+ <entry><type>boolean</type></entry>
+ <entry><constant>TRUE</constant></entry>
+ <entry>Capture the signal that implements
+ <function>mp:interrupt-process</function>.</entry>
+ </row>
+ <row>
+ <entry><constant>SIGNAL_HANDLING_THREAD</constant></entry>
+ <entry><type>boolean</type></entry>
+ <entry><constant>TRUE</constant></entry>
+ <entry>Create a signal to capture and process asynchronous threads (See
+ <xref linkend="ext.signals.asynchronous-handler"/>).</entry>
+ </row>
+ <row>
+ <entry><constant>BOOTED</constant></entry>
+ <entry><type>boolean</type></entry>
+ <entry><constant>TRUE/FALSE</constant></entry>
+ <entry>Has &ECL; booted (read only).</entry>
+ </row>
+ <row>
+ <entry><constant>BIND_STACK_SIZE</constant></entry>
+ <entry><type>cl_index</type></entry>
+ <entry><constant>8192</constant></entry>
+ <entry>Size of stack for binding special variables.</entry>
+ </row>
+ <row>
+ <entry><constant>BIND_STACK_SAFETY_AREA</constant></entry>
+ <entry><type>cl_index</type></entry>
+ <entry><constant>128</constant></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><constant>FRAME_STACK_SIZE</constant></entry>
+ <entry><type>cl_index</type></entry>
+ <entry><constant>2048</constant></entry>
+ <entry>Size of stack for nonlocal jumps.</entry>
+ </row>
+ <row>
+ <entry><constant>FRAME_STACK_SAFETY_AREA</constant></entry>
+ <entry><type>cl_index</type></entry>
+ <entry><constant>128</constant></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><constant>LISP_STACK_SIZE</constant></entry>
+ <entry><type>cl_index</type></entry>
+ <entry><constant>32768</constant></entry>
+ <entry>Size of interpreter stack.</entry>
+ </row>
+ <row>
+ <entry><constant>LISP_STACK_SAFETY_AREA</constant></entry>
+ <entry><type>cl_index</type></entry>
+ <entry><constant>128</constant></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><constant>C_STACK_SIZE</constant></entry>
+ <entry><type>cl_index</type></entry>
+ <entry><constant>131072</constant></entry>
+ <entry>Size of C stack (not exact).</entry>
+ </row>
+ <row>
+ <entry><constant>C_STACK_SAFETY_AREA</constant></entry>
+ <entry><type>cl_index</type></entry>
+ <entry><constant>4192</constant></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><constant>SIGALTSTACK_SIZE</constant></entry>
+ <entry><type>cl_index</type></entry>
+ <entry><constant>1</constant></entry>
+ <entry>If nonzero, run C signal handler in an alternative
+ signal. A small value is automatically incremented.</entry>
+ </row>
+ <row>
+ <entry><constant>THREAD_INTERRUPT_SIGNAL</constant></entry>
+ <entry><type>unsigned int</type></entry>
+ <entry><constant>0</constant></entry>
+ <entry>If nonzero, specify the unix signal which is used to
+ communicate different Lisp threads.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- ecl_get_option() -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.embed.ecl_get_option">
+ <refnamediv>
+ <refname><function>ecl_get_option</function></refname>
+ <refpurpose>Read the value of a boot option.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcprototype>
+ <funcdef>cl_fixnum <function>ecl_get_option</function></funcdef>
+ <paramdef>int <parameter>option</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>option</replaceable></term>
+ <listitem><para>An integer from <xref linkend="table.boot_options"/>.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This functions reads the value of different options that have
+ to be customized <emphasis>before</emphasis> &ECL; boots. The table
+ of options and default values is <xref linkend="table.boot_options"/>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- ecl_clear_interrupts() -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.embed.ecl_clear_interrupts">
+ <refnamediv>
+ <refname><function>ecl_clear_interrupts</function></refname>
+ <refpurpose>Clear all pending signals and exceptions.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcprototype>
+ <funcdef><function>ecl_clear_interrupts</function></funcdef>
+ <paramdef></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This macro clears all pending interrupts.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+ <para> <xref linkend="ref.embed.ecl_disable_interrupts"/> and <xref
+ linkend="ref.embed.ecl_enable_interrupts"/>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- ecl_disable_interrupts() -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.embed.ecl_disable_interrupts">
+ <refnamediv>
+ <refname><function>ecl_disable_interrupts</function></refname>
+ <refpurpose>Postpone handling of signals and exceptions.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcprototype>
+ <funcdef><function>ecl_disable_interrupts</function></funcdef>
+ <paramdef></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This macro sets a thread-local flag indicating that all received
+ signals should be queued for later processing.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+ <para><xref linkend="ref.embed.ecl_enable_interrupts"/> and <xref
+ linkend="ref.embed.ecl_clear_interrupts"/>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- ecl_enable_interrupts() -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.embed.ecl_enable_interrupts">
+ <refnamediv>
+ <refname><function>ecl_enable_interrupts</function></refname>
+ <refpurpose>Activate handling of signals and exceptions.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <?dbhtml funcsynopsis-style='ansi'?>
+ <funcprototype>
+ <funcdef><function>ecl_enable_interrupts</function></funcdef>
+ <paramdef></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This macro sets a thread-local flag indicating that all received
+ signals can be handled. If there are any pending signals, they will be
+ immediately processed.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+ <para><xref
+ linkend="ref.embed.ecl_disable_interrupts"/> and <xref
+ linkend="ref.embed.ecl_clear_interrupts"/>.
+ </para>
+ </refsect1>
+</refentry>
+</section>
+</chapter>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+ -->
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Memory Management</title>
+<section xml:id="ext.memory.dict">
+<title>Memory Management Reference</title>
+
+<!-- ====================================================================== -->
+<!-- EXT:STACK-OVERFLOW -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.memory.stack-overflow">
+ <refnamediv>
+ <refname><classname>ext:stack-overflow</classname></refname>
+ <refpurpose>Stack overflow condition.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Class Precedence List</title>
+ <para>
+ <classname>ext:stack-overflow</classname>,
+ <classname>storage-condition</classname>,
+ <classname>serious-condition</classname>,
+ <classname>condition</classname>,
+ <classname>t</classname>
+ </para>
+ </refsynopsisdiv>
+
+ <refsynopsisdiv>
+ <title>Methods</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:stack-overflow-size</funcdef>
+ <paramdef><parameter>condition</parameter></paramdef>
+ <modifier><replaceable>integer</replaceable></modifier>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>ext:stack-overflow-type</funcdef>
+ <paramdef><parameter>condition</parameter></paramdef>
+ <modifier><replaceable>concept</replaceable></modifier>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>integer</replaceable></term>
+ <listitem><para>A non-negative integer.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>concept</replaceable></term>
+ <listitem><para>A symbol from <xref
+ linkend="table.memory.limits"/>, except
+ <varname>ext:heap-size</varname>.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This condition is signaled when one of the stack limits in
+ <xref linkend="table.memory.limits"/> are violated or dangerously
+ approached. It can be handled by resetting the limits and
+ continuing, or jumping to an outer control point.</para>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- EXT:STORAGE-EXHAUSTED -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.memory.storage-exhausted">
+ <refnamediv>
+ <refname><classname>ext:storage-exhausted</classname></refname>
+ <refpurpose>Memory overflow condition.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Class Precedence List</title>
+ <para>
+ <classname>ext:storage-exhausted</classname>,
+ <classname>storage-condition</classname>,
+ <classname>serious-condition</classname>,
+ <classname>condition</classname>,
+ <classname>t</classname>
+ </para>
+ </refsynopsisdiv>
+
+
+ <refsect1>
+ <title>Description</title>
+ <para>This condition is signaled when &ECL; exhausts the
+ <varname>ext:heap-size</varname> limit from <xref
+ linkend="table.memory.limits"/>. In handling this condition &ECL; follows
+ this logic</para>
+ <itemizedlist>
+ <listitem><para>If the heap size limit was set to 0 (that is no limit), but
+ there is some free space in the safety region &ECL; frees this space and
+ issues a non-restartable error. The user may jump to an outer point or
+ quit.</para></listitem>
+
+ <listitem><para>If the heap size had a finite limit, &ECL; offers the user
+ the chance to resize it, issuing a restartable condition. The user may at
+ this point use <code>(ext:set-limit 'ext:heap-size 0)</code> to remove the
+ heap limit and avoid further messages, or use the <code>(continue)</code>
+ restart to let &ECL; enlarge the heap by some amount.</para></listitem>
+
+ <listitem><para>Independently of the heap size limit, if &ECL; finds that
+ ther is no space to free or to grow, &ECL; simply quits. There will be no
+ chance to do some cleanup because there is no way to cons any additional
+ data.</para></listitem>
+ </itemizedlist>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- EXT:GET-FINALIZER -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.memory.get-finalizer">
+ <refnamediv>
+ <refname><function>ext:get-finalizer</function></refname>
+ <refpurpose>Return finalizer associated to an object.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:get-finalizer</funcdef>
+ <paramdef><parameter>object</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>object</replaceable></term>
+ <listitem><para>Any lisp object.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This function returns the finalizer associated to an object, or &nil;.</para>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- EXT::GET-LIMIT -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.memory.get-limit">
+ <refnamediv>
+ <refname><function>ext:get-limit</function></refname>
+ <refpurpose>Query a memory or stack limit.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:get-limit</funcdef>
+ <paramdef><parameter>concept</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>concept</replaceable></term>
+ <listitem><para>A symbol.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Queries the different memory and stack limits that condition
+ &ECL;'s behavior. The value to be queried is denoted by the symbol
+ <replaceable>concept</replaceable>, which should be one from the
+ list <xref linkend="table.memory.limits"/></para>
+
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- EXT::SET-FINALIZER -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.memory.set-finalizer">
+ <refnamediv>
+ <refname><function>ext:set-finalizer</function></refname>
+ <refpurpose>Associate a finalizer to an object.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:set-finalizer</funcdef>
+ <paramdef><parameter>object</parameter></paramdef>
+ <paramdef><parameter>function</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>object</replaceable></term>
+ <listitem><para>Any lisp object.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>function</replaceable></term>
+ <listitem><para>A function or closure that takes one argument or &nil;.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>If <replaceable>function</replaceable> is &nil; no finalizer is
+ associated to the object. Otherwise <replaceable>function</replaceable> must
+ be a function or a closure of one argument, which will be invoked before the
+ object is destroyed.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>Close a file associated to an object.</para>
+<programlisting>
+(defclass my-class () ((file :initarg :file :initform nil)))
+
+(defun finalize-my-class (x)
+ (let ((s (slot-value x 'file)))
+ (when s (format t "~%;;; Closing" s) (close s))))
+
+(defmethod initialize-instance :around ((my-instance my-class) &rest args)
+ (ext:set-finalizer my-instance #'finalize-my-class)
+ (call-next-method))
+
+(progn
+ (make-instance 'my-class :file (open "~/.ecl.old" :direction :input))
+ nil)
+
+(si::gc t)
+(si::gc t)
+
+;; Closing
+</programlisting>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- EXT::SET-LIMIT -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.memory.set-limit">
+ <refnamediv>
+ <refname><function>ext:set-limit</function></refname>
+ <refpurpose>Set a memory or stack limit.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:set-limit</funcdef>
+ <paramdef><parameter>concept</parameter></paramdef>
+ <paramdef><parameter>value</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>concept</replaceable></term>
+ <listitem><para>A symbol.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>function</replaceable></term>
+ <listitem><para>A positive integer.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Changes the different memory and stack limits that condition
+ &ECL;'s behavior. The value to be changed is denoted by the symbol
+ <replaceable>concept</replaceable>, while the
+ <replaceable>value</replaceable> is the new maximum size. The valid
+ symbols and units are listed in <xref
+ linkend="table.memory.limits"/>.</para>
+
+ <para>Note that the limit has to be positive, but it may be smaller
+ than the previous value of the limit. However, if the supplied value
+ is smaller than what &ECL; is using at the moment, the new value
+ will be silently ignored.</para>
+
+ <table xml:id="table.memory.limits">
+ <title>Customizable memory limits</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Concept</entry>
+ <entry>Units</entry>
+ <entry>Default</entry>
+ <entry>Command line</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><varname>ext:frame-stack</varname></entry>
+ <entry>Nested frames</entry>
+ <entry>2048</entry>
+ <entry>--frame-stack</entry>
+ </row>
+ <row>
+ <entry><varname>ext:binding-stack</varname></entry>
+ <entry>Bindings</entry>
+ <entry>8192</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><varname>ext:c-stack</varname></entry>
+ <entry>Bytes</entry>
+ <entry>128 kilobytes</entry>
+ <entry>--c-stack</entry>
+ </row>
+ <row>
+ <entry><varname>ext:heap-size</varname></entry>
+ <entry>Bytes</entry>
+ <entry>256 megabytes</entry>
+ <entry>--heap-size</entry>
+ </row>
+ <row>
+ <entry><varname>ext:lisp-stack</varname></entry>
+ <entry>Bytes</entry>
+ <entry>32 kilobytes</entry>
+ <entry>--lisp-stack</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </refsect1>
+
+</refentry>
+</section>
+</chapter>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+ -->
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Multithreading</title>
+<section xml:id="ext.mp.dict"><title>Multithreading Reference</title>
+
+<!-- ====================================================================== -->
+<!-- MP:ALL-PROCESSES -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.all-processes">
+ <refnamediv>
+ <refname><function>mp:all-processes</function></refname>
+ <refpurpose>Return the list of active processes.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:all-processes</funcdef>
+ <paramdef></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>Returns the list of processes associated to running tasks. The list is
+ a fresh new one and can be destructively modified. However, it may happen
+ that the output list is not up to date, because some of the tasks has expired
+ before this copy is returned.</para>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:EXIT-PROCESS -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.exit-process">
+ <refnamediv>
+ <refname><function>mp:exit-process</function></refname>
+ <refpurpose>Exit the task from which it is invoked.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:exit-process</funcdef>
+ <paramdef></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>When called from a running task, this function immediately causes the
+ task to finish. When invoked from the main thread, it is equivalent to
+ invoking <xref linkend="ref.quit"/> with exit code 0.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>See <xref linkend="ref.mp.interrupt-process"/>.</para>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:INTERRUPT-PROCESS -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.interrupt-process">
+ <refnamediv>
+ <refname><function>mp:interrupt-process</function></refname>
+ <refpurpose>Interrupt a task.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:interrupt-process</funcdef>
+ <paramdef><parameter>process</parameter></paramdef>
+ <paramdef><parameter>function</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>process</replaceable></term>
+ <listitem><para>An object of type
+ <replaceable>mp:process</replaceable>.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>function</replaceable></term>
+ <listitem><para>A function, which is to be executed in the interrupted
+ process.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This function sends a signal to a running task. When the task is
+ free to process that signal, it will stop whatever it is doing and
+ execute the given <replaceable>function</replaceable>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>Kill a task that is doing nothing (See <xref linkend="ref.mp.process-kill"/>).</para>
+<programlisting>
+(flet ((task-to-be-killed ()
+ (loop (sleep 1)) ; Infinite loop
+ ))
+ (let ((task (mp:process-run-function 'background #'task-to-be-killed)))
+ (sleep 10)
+ (mp:interrupt-process task 'mp:exit-process)))
+</programlisting>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:GET-LOCK -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.get-lock">
+ <refnamediv>
+ <refname><function>mp:get-lock</function></refname>
+ <refpurpose>Try to obtain a lock.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:get-lock</funcdef>
+ <paramdef><parameter>lock</parameter></paramdef>
+ <paramdef><parameter>&optional;</parameter></paramdef>
+ <paramdef><parameter>wait</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>lock</replaceable></term>
+ <listitem><para>An object of type
+ <replaceable>mp:lock</replaceable>.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>wait</replaceable></term>
+ <listitem><para>Whether to wait to obtain the lock. Defaults to
+ &nil;.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This function tries to obtain exclusive use of a lock. If
+ <replaceable>wait</replaceable> is &t;, and another task owns the lock, it
+ may wait until the lock has been released. If <replaceable>wait</replaceable>
+ is &nil; it will return true if and only if it succeeded on acquiring
+ the lock.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>See <xref linkend="ref.mp.with-lock"/>.</para>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:GIVEUP-LOCK -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.giveup-lock">
+ <refnamediv>
+ <refname><function>mp:giveup-lock</function></refname>
+ <refpurpose>Release a lock we have obtained before.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:giveup-lock</funcdef>
+ <paramdef><parameter>lock</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>lock</replaceable></term>
+ <listitem><para>An object of type
+ <replaceable>mp:lock</replaceable>.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This function releases a lock which had been previously obtained using
+ <xref linkend="ref.mp.get-lock"/>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>See <xref linkend="ref.mp.with-lock"/>.</para>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:MAKE-LOCK -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.make-lock">
+ <refnamediv>
+ <refname><function>mp:make-lock</function></refname>
+ <refpurpose>Create a new lock.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:make-lock</funcdef>
+ <paramdef><parameter>&key;</parameter></paramdef>
+ <paramdef><parameter>name</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>name</replaceable></term>
+ <listitem><para>A symbol to name the lock. Names not be unique. It defaults
+ to &nil;.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This function creates a lock object that can be use to synchronize
+ different tasks. The own is initally free and not owned by any task. Locks
+ are typically implemented using Posix mutexes. When garbage collected, a lock
+ is automatically freed.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>See <xref linkend="ref.mp.with-lock"/>.</para>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:MAKE-PROCESS -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.make-process">
+ <refnamediv>
+ <refname><function>mp:make-process</function></refname>
+ <refpurpose>Create a new thread.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:make-process</funcdef>
+ <paramdef><parameter>&key;</parameter></paramdef>
+ <paramdef><parameter>name</parameter></paramdef>
+ <paramdef><parameter>initial-bindings</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>name</replaceable></term>
+ <listitem><para>A symbol to name the process. Processes can be
+ unnamed and names need not be unique.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>initial-bindings</replaceable></term>
+ <listitem><para>The list of special variables which will be local to
+ the new process. It defaults to &t;, which means copying all variables
+ which are local to this process.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This function creates a separate task, with a name, set of variable
+ bindings and no function to run.</para>
+
+ <para>See also <xref linkend="ref.mp.process-run-function"/>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>See <xref linkend="ref.mp.process-enable"/></para>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:PROCESS-ACTIVE-P -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.process-active-p">
+ <refnamediv>
+ <refname><function>mp:process-active-p</function></refname>
+ <refpurpose>Determine whether a task is running.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:process-active-p</funcdef>
+ <paramdef><parameter>process</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>process</replaceable></term>
+ <listitem><para>An object of type <replaceable>mp:process</replaceable>.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>Returns true if the task is currently running.</para>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:PROCESS-ENABLE -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.process-enable">
+ <refnamediv>
+ <refname><function>mp:process-enable</function></refname>
+ <refpurpose>Start up a task which was not running.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:process-enable</funcdef>
+ <paramdef><parameter>process</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>process</replaceable></term>
+ <listitem><para>An object of type <replaceable>mp:process</replaceable>.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>The argument to this function should be a process created by <xref
+ linkend="ref.mp.make-process"/>, which has a function associated as per <xref
+ linkend="ref.mp.process-preset"/> but which is not yet running. After
+ invoking this function a new thread will be created in which the associated
+ function will be executed.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>The following is a possible implementation of <xref linkend="ref.mp.process-run-function"/>.</para>
+<programlisting>
+(defun process-run-function (process-name process-function &rest args)
+ (let ((process (mp:make-process name)))
+ (apply #'mp:process-preset process function args)
+ (mp:process-enable process)))
+</programlisting>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:PROCESS-KILL -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.process-kill">
+ <refnamediv>
+ <refname><function>mp:process-kill</function></refname>
+ <refpurpose>Try to stop a running task.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:process-kill</funcdef>
+ <paramdef><parameter>process</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>process</replaceable></term>
+ <listitem><para>An object of type
+ <replaceable>mp:process</replaceable>.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This function tries to stop a running task. Killing a process
+ may fail if the task has disabled interrupts.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>Kill a task that is doing nothing.</para>
+<programlisting>
+(flet ((task-to-be-killed ()
+ (loop (sleep 1)) ; Infinite loop
+ ))
+ (let ((task (mp:process-run-function 'background #'task-to-be-killed)))
+ (sleep 10)
+ (mp:process-kill task)))
+</programlisting>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:PROCESS-NAME -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.process-name">
+ <refnamediv>
+ <refname><function>mp:process-name</function></refname>
+ <refpurpose>Return the name of a task.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:process-active-p</funcdef>
+ <paramdef><parameter>process</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>process</replaceable></term>
+ <listitem><para>An object of type <replaceable>mp:process</replaceable>.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>Returns the name of the given task, if any.</para>
+ </refsect1>
+
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:PROCESS-PRESET -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.process-preset">
+ <refnamediv>
+ <refname><function>mp:process-preset</function></refname>
+ <refpurpose>Associate a function to a process.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:process-preset</funcdef>
+ <paramdef><parameter>process</parameter></paramdef>
+ <paramdef><parameter>function</parameter></paramdef>
+ <paramdef><parameter>&rest;</parameter></paramdef>
+ <paramdef><parameter>function-args</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>process</replaceable></term>
+ <listitem><para>An object of type
+ <replaceable>mp:process</replaceable>.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>function</replaceable></term>
+ <listitem><para>An interpret or compiled function.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>function-args</replaceable></term>
+ <listitem><para>One or more arguments for the function
+ above.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This function associates a function to a stopped task. This function
+ will be the entry point when the task is enabled in the future.</para>
+
+ <para>See also <xref linkend="ref.mp.process-run-function"/>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>See <xref linkend="ref.mp.process-enable"/>.</para>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:PROCESS-RUN-FUNCTION -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.process-run-function">
+ <refnamediv>
+ <refname><function>mp:process-run-function</function></refname>
+ <refpurpose>Create a task and execute a function in it.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp:process-run-function</funcdef>
+ <paramdef><parameter>name</parameter></paramdef>
+ <paramdef><parameter>function</parameter></paramdef>
+ <paramdef><parameter>&rest;</parameter></paramdef>
+ <paramdef><parameter>function-args</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>name</replaceable></term>
+ <listitem><para>A symbol to name the process. Processes can be
+ unnamed and names need not be unique.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>function</replaceable></term>
+ <listitem><para>A function object, interpreted or compiled.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>function-args</replaceable></term>
+ <listitem><para>One or more arguments which will be passed to the
+ function.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This function creates a new process using <xref
+ linkend="ref.mp.make-process"/>, associates a function to it and then
+ starts it using <xref linkend="ref.mp.process-preset"/>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>As an example, the following code starts a background task that
+ outputs a list of numbers, one every second:</para>
+<programlisting>
+(flet ((count-numbers (end-number)
+ (dotimes (i end-number)
+ (format t "~%;;; Counting: ~i" i)
+ (terpri)
+ (sleep 1))))
+ (mp:process-run-function 'counter #'count-numbers 10))
+</programlisting>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- MP:WITH-LOCK -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.mp.with-lock">
+ <refnamediv>
+ <refname><function>mp:with-lock</function></refname>
+ <refpurpose>Synchronize a piece of code between different tasks.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>mp::with-lock</funcdef>
+ <paramdef>(<parameter>lock</parameter>)</paramdef>
+ <paramdef><parameter>&body;</parameter></paramdef>
+ <paramdef><parameter>body</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>It grabs a lock, executes a piece of lisp code and releases the lock at
+ the end. The inner forms are protected so that when any condition is
+ signalled the lock is released.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>Ensure each task increments the counter properly. The lock is
+ required because INCF is not an atomic operation.</para>
+<programlisting>
+(defvar *counter* 0)
+(defvar *counter-lock* (mp:make-lock :name 'counter))
+
+(flet ((task (name)
+ (loop while (<= *counter* 10)
+ do (progn
+ (sleep 1)
+ (with-lock (*counter-lock*)
+ (format t "~%;;; ~A counts ~D" name *counter*)
+ (terpri)
+ (incf *counter*))))))
+ (mp:process-run-function 'ana #'task 'ana)
+ (mp:process-run-function 'jose #'task 'jose))
+</programlisting>
+ </refsect1>
+</refentry>
+</section>
+</chapter>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+ -->
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en"><reference xml:id="os.dict"><title>OS Reference</title>
+
+ <!-- ====================================================================== -->
+ <!-- EXT:*HELP-MESSAGE* -->
+ <!-- ====================================================================== -->
+
+ <refentry xml:id="ref._help-message_">
+ <refnamediv>
+ <refname><varname>ext:*help-message*</varname></refname>
+ <refpurpose>Command line help message</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Variable</title>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>A string</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Initial value</term>
+ <listitem><para>&ECL; help message</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This variable contains the help message which is output when &ECL; is
+ invoked with the <option>--help</option>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>See <xref linkend="ref.process-command-args"/>.</para>
+ </refsect1>
+ </refentry>
+
+ <!-- ====================================================================== -->
+ <!-- EXT:+LISP-INIT-FILES+ -->
+ <!-- ====================================================================== -->
+
+ <refentry xml:id="ref._lisp-init-file-list_">
+ <refnamediv>
+ <refname><varname>ext:*lisp-init-file-list*</varname></refname>
+ <refpurpose>&ECL; initialization files.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Constant</title>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>A list of pathname designators.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Initial value</term>
+ <listitem><para><literal>'("~/.ecl" "~/.eclrc")</literal></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This variable contains the names of initialization files that are
+ loaded by &ECL; or embedding programs. The loading of initialization files
+ happens automatically in &ECL; unless invoked with the option
+ <option>-norc</option>. Whether initialization files are loaded or not is
+ controlled by the command line options rules, as described in <xref
+ linkend="ref.process-command-args"/>.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>See <xref linkend="ref.process-command-args"/>.</para>
+ </refsect1>
+ </refentry>
+
+ <!-- ====================================================================== -->
+ <!-- EXT:+DEFAULT-COMMAND-ARG-RULES+ -->
+ <!-- ====================================================================== -->
+
+ <refentry xml:id="ref._default-command-arg-rules_">
+ <refnamediv>
+ <refname><varname>ext:+default-command-arg-rules+</varname></refname>
+ <refpurpose>&ECL; command line options</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Constant</title>
+ <variablelist>
+ <varlistentry>
+ <term>Type</term>
+ <listitem><para>A list of lists.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This constant contains a list of rules for parsing the command line
+ arguments. This list is made of all the options which &ECL; accepts by
+ default. It can be passed as first argument to <xref
+ linkend="ref.process-command-args"/>, and you can use it as a starting point
+ to extend &ECL;.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+ <para>See <xref linkend="ref.process-command-args"/>.</para>
+ </refsect1>
+ </refentry>
+
+ <!-- ====================================================================== -->
+ <!-- EXT:COMMAND-ARGS -->
+ <!-- ====================================================================== -->
+
+ <refentry xml:id="ref.command-args">
+ <refnamediv>
+ <refname><function>ext:command-args</function></refname>
+ <refpurpose>Original list of command line arguments.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:command-args</funcdef>
+ <void></void>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term>returns</term>
+ <listitem><para>A list of strings.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This function returns the list of command line arguments passed to
+ either &ECL; or the program it was embedded in. The output is a list of
+ strings and it corresponds to the <varname>argv</varname> vector in a C
+ program. Typically, the first argument is the name of the program as it was
+ invoked. You should not count on ths filename to be resolved.</para>
+ </refsect1>
+
+ </refentry>
+
+ <!-- ====================================================================== -->
+ <!-- EXT:PROCESS-COMMAND-ARGS -->
+ <!-- ====================================================================== -->
+
+ <refentry xml:id="ref.process-command-args">
+ <refnamediv>
+ <refname><function>ext:process-command-args</function></refname>
+ <refpurpose>Process command line arguments.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:process-command-args</funcdef>
+ <paramdef><parameter>&key;</parameter></paramdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ <paramdef><parameter>rules</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>args</replaceable></term>
+ <listitem><para>A list of strings. Defaults to the output of <xref
+ linkend="ref.command-args"/></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>rules</replaceable></term>
+ <listitem><para>A list of lists. Defaults to the value of <xref
+ linkend="ref._default-command-arg-rules_"/></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This function processes the command line arguments passed to either
+ &ECL; or the program that embeds it. It uses the list of rules
+ <replaceable>rules</replaceable>, which has the following syntax:
+<synopsis>(option-name nargs template [:stop | :noloadrc | :loadrc]*)</synopsis>
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>option-name</replaceable></term>
+ <listitem><para>A string with the option prefix as typed by the user. For
+ instance <option>--help</option>, <option>-?</option>,
+ <option>--compile</option>, etc.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>nargs</replaceable></term>
+ <listitem><para>A nonnegative integer denoting the number of arguments
+ taken by this option.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>template</replaceable></term>
+ <listitem><para>A lisp form, not evaluated, where numbers from 0 to
+ <replaceable>nargs</replaceable> will be replaced by the corresponding
+ option argument.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>:STOP</symbol></term>
+ <listitem><para>If present, parsing of arguments stops after this option
+ is found and processed. The list of remaining arguments is passed to
+ the rule. &ECL;'s top-level uses this option with the <symbol>--</symbol>
+ command line option to set <symbol>ext:*unprocessed-ecl-command-args*</symbol>
+ to the list of remaining arguments.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>:NOLOADRC</symbol> and <symbol>:LOADRC</symbol></term>
+ <listitem><para>Determine whether the lisp initalization file (<xref
+ linkend="ref._lisp-init-file-list_"/>) will be loaded before processing
+ all forms.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para><function>EXT:PROCESS-COMMAND-ARGS</function> works as follows. First
+ of all, it parses all the command line arguments, except for the first one,
+ which is assumed to contain the program name. Each of these arguments is
+ matched against the rules, sequentially, until one of the patterns
+ succeeeds.</para>
+
+ <para>A special name <literal>"*DEFAULT*"</literal>, matches any unknown
+ command line option. If there is no <literal>"*DEFAULT*"</literal> rule and
+ no match is found, an error is signalled. For each rule that succeeds, the
+ function constructs a lisp statement using the
+ <replaceable>template</replaceable>.</para>
+
+ <para>After all arguments have been processed,
+ <function>EXT:PROCESS-COMMAND-ARGS</function>, and there were no occurences
+ of <symbol>:NOLOADRC</symbol>, one of the files listed in <xref
+ linkend="ref._lisp-init-file-list_"/> will be loaded. Finally, the list of
+ lisp statements will be evaluated.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>The following piece of code implements the <command>ls</command>
+ command using lisp.<footnote><para>Instructions for building this program
+ are found under
+ <filename>ecl/examples/cmdline/ls.lsp</filename></para></footnote></para>
+<!-- When changing, check ecl/examples/cmdline/ls.lsp -->
+<programlisting>
+(setq ext:*help-message* "
+ls [--help | -?] filename*
+ Lists the file that match the given patterns.
+")
+
+(defun print-directory (pathnames)
+ (format t "~{~A~%~}"
+ (mapcar #'(lambda (x) (enough-namestring x (si::getcwd)))
+ (mapcan #'directory (or pathnames '("*.*" "*/"))))))
+
+(defconstant +ls-rules+
+'(("--help" 0 (progn (princ ext:*help-message* *standard-output*) (ext:quit 0)))
+ ("-?" 0 (progn (princ ext:*help-message* *standard-output*) (ext:quit 0)))
+ ("*DEFAULT*" 1 (print-directory 1) :stop)))
+
+(let ((ext:*lisp-init-file-list* NIL)) ; No initialization files
+ (handler-case (ext:process-command-args :rules +ls-rules+)
+ (error (c)
+ (princ ext:*help-message* *error-output*)
+ (ext:quit 1))))
+(ext:quit 0)
+</programlisting>
+ </refsect1>
+ </refentry>
+
+ <!-- ====================================================================== -->
+ <!-- EXT:QUIT -->
+ <!-- ====================================================================== -->
+
+ <refentry xml:id="ref.quit">
+ <refnamediv>
+ <refname><function>ext:quit</function></refname>
+ <refpurpose>Exit &ECL;.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:quit</funcdef>
+ <paramdef>&optional;</paramdef>
+ <paramdef><parameter>exit-code</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>exit-code</replaceable></term>
+ <listitem><para>An integer between 0 and 255</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This function abruptly stops the execution of the program in which
+ &ECL; is embedded. Depending on the platform, several other functions will
+ be invoked to free resources, close loaded modules, etc.</para>
+
+ <para>The exit code is the code seen by the parent process that invoked
+ this program. Normally a code other than zero denotes an error.</para>
+ </refsect1>
+ </refentry>
+
+ <!-- ====================================================================== -->
+ <!-- EXT:RUN-PROGRAM -->
+ <!-- ====================================================================== -->
+ <refentry xml:id="ref.run-program">
+ <refnamediv>
+ <refname><function>ext:run-program</function></refname>
+ <refpurpose>Start and communicate with a child process.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:run-program</funcdef>
+ <paramdef><parameter>command</parameter></paramdef>
+ <paramdef><parameter>argv</parameter></paramdef>
+ <paramdef>&key;</paramdef>
+ <paramdef>input</paramdef>
+ <paramdef>output</paramdef>
+ <paramdef>error</paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>input</replaceable></term>
+ <listitem><para>One of <symbol>:STREAM</symbol>, <symbol>T</symbol> or
+ <symbol>NIL</symbol>, defaults to
+ <symbol>:STREAM</symbol></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>output</replaceable></term>
+ <listitem><para>One of <symbol>:STREAM</symbol>, <symbol>T</symbol> or
+ <symbol>NIL</symbol>, defaults to
+ <symbol>:STREAM</symbol></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>error</replaceable></term>
+ <listitem><para>One of <symbol>:OUTPUT</symbol>, <symbol>T</symbol> or
+ <symbol>NIL</symbol>, defaults to
+ <symbol>T</symbol></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This function creates a external process by launching the program
+ <replaceable>command</replaceable> with the arguments from the list
+ <replaceable>argv</replaceable>.</para>
+
+ <para>The arguments <replaceable>input</replaceable>,
+ <replaceable>output</replaceable> and <replaceable>error</replaceable> are
+ used to intercept the standard input, output and error streams of the
+ program. A value of <symbol>:STREAM</symbol> means a lisp stream will be
+ created to communicate with the child process. A value of
+ <symbol>NIL</symbol> means that the data from this pipe will be
+ discarded. The vaule of <symbol>T</symbol> means that the child process will
+ use the parent's standard input, output or error channels. For instance, if
+ &ECL; writes to the console and you pass a value of
+ <replaceable>output</replaceable> equal to <symbol>:STREAM</symbol>, the
+ child process will also output to the console. Finally, the error messages
+ of the child process are redirected to the same pipe as its standard
+ output when <replaceable>error</replaceable> takes the value
+ <symbol>:OUTPUT</symbol>.</para>
+
+ <para>If the child process was succesfully launched, this function outputs a
+ lisp stream to which we one may write, read or do both things, depending on
+ the arguments <replaceable>input</replaceable> and
+ <replaceable>output</replaceable>. If an error happened during the
+ preparation of the child process (for instance the program was not found),
+ this function returns <replaceable>NIL</replaceable>.</para>
+
+ <para>The design of this function is inspired by the function of same name
+ in &CMUCL; and &SBCL;.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>List all users in a Unix system. We use the <command>sed</command>
+ command to parse the file with the list of users, removing comments and
+ information other than the user names:
+<programlisting>(defun all-users (&optional (file "/etc/passwd"))
+ (let ((s (ext:run-program "sed"
+ (list "-e" "/^#.*$/d;/^[^:]*$/d;s,^\\([^:]*\\).*$,\\1,g"
+ file)
+ :input NIL :output :STREAM :error NIL)))
+ (unless s
+ (error "Unable to parse password file"))
+ (loop for x = (read s NIL NIL)
+ while x
+ collect x)))</programlisting></para>
+
+ <para>Make a directory. Redirect standard error output to the same as the
+ output:
+<programlisting>(ext:run-program "mkdir" '("./tmp") :output :STREAM :error :OUTPUT)
+</programlisting>
+</para>
+
+ <para>Same as before, but now both the output and the standard error are
+ discarded
+<programlisting>(ext:run-program "mkdir" '("./tmp") :output NIL :error :OUTPUT)
+</programlisting>
+</para>
+ </refsect1>
+ </refentry>
+
+ <!-- ====================================================================== -->
+ <!-- EXT:SYSTEM -->
+ <!-- ====================================================================== -->
+
+ <refentry xml:id="ref.system">
+ <refnamediv>
+ <refname><function>ext:system</function></refname>
+ <refpurpose>Invoke a command using the shell.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Function</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:system</funcdef>
+ <paramdef><parameter>command</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>command</replaceable></term>
+ <listitem><para>A string</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem><para>An integer (0-255) with the exit code of the
+ program</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This function executes a command in the shell. In Unix systems,
+ typically the environment variable <symbol>SHELL</symbol> determines which
+ program will be invoked, while in Windows <command>CMD.EXE</command> is
+ used. The string may thus be any valid command that the shell accepts and
+ in can contain higher level elements such as input/output
+ redirection.</para>
+
+ <para>As an example, the following function uses an external editor to
+ modify a lisp file and, if successful, loads the changed sources:</para>
+ <programlisting>
+(defun edit (filename)
+ (let* ((editor #+windows "notepad.exe"
+ #-windows "/usr/bin/emacs")
+ (command (concatenate 'string editor " " filename)))
+ (when (zerop (ext:system command))
+ (load filename))))
+ </programlisting>
+ </refsect1>
+ </refentry>
+
+</reference></book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+ -->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter>
+<title>Signals</title>
+<section xml:id="ext.signals.dict">
+<title>Signals Reference</title>
+
+<!-- ====================================================================== -->
+<!-- EXT:WITH-INTERRUPTS -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.signals.with-interrupts">
+ <refnamediv>
+ <refname><function>ext:with-interrupts</function></refname>
+ <refpurpose>Execute code with interrupts optionally enabled.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:with-interrupts</funcdef>
+ <paramdef>&body; <param>body</param></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Executes the given body with all interrupts enabled. Since
+ interrupts are normally enabled, this macro only makes sense if
+ there is an outer <function>ext:without-interrupts</function> with
+ a corresponding <function>ext:allow-with-interrupts</function>:
+ interrupts are not enabled if any outer
+ <function>mp:without-interrupts</function> is not accompanied by
+ <function>mp:allow-with-interrupts</function>.</para>
+ </refsect1>
+</refentry>
+
+<!-- ====================================================================== -->
+<!-- EXT:WITHOUT-INTERRUPTS -->
+<!-- ====================================================================== -->
+
+<refentry xml:id="ref.signals.without-interrupts">
+ <refnamediv>
+ <refname><function>ext:without-interrupts</function></refname>
+ <refpurpose>Execute code without being interrupted.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ext:without-interrupts</funcdef>
+ <paramdef>&body; <param>body</param></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>Executes the given body with all interrupts disabled. This
+ macro is compatible with the one in &SBCL; and as such it also
+ defines three other local macros
+ <function>ext:allow-with-interrupts</function>,
+ <function>ext:with-local-interrupts</function> and
+ <function>ext:with-restored-interrupts</function>.</para>
+
+ <para>Deferrable interrupts include most blockable POSIX signals,
+ and <function>mp:interrupt-process</function>. Does not interfere
+ with garbage collection, and does not inhibit scheduling of other
+ threads.</para>
+
+ <para>This macro binds <function>allow-with-interrupts</function>,
+ <function>with-local-interrupts</function> and
+ <function>with-restored-interrupts</function> as a local
+ macros.</para>
+
+ <para><function>ext:with-restored-interrupts</function> executes
+ the body with interrupts enabled if and only if the
+ <function>ext:without-interrupts</function> was in an environment
+ in which interrupts were allowed.</para>
+
+ <para><function>ext:allow-with-interrupts</function> allows the
+ <function>ext:with-interrupts</function> to take effect during the
+ dynamic scope of its body, unless there is an outer
+ <function>ext:without-interrupts</function> without a
+ corresponding
+ <function>ext:allow-with-interrupts</function>.</para>
+
+ <para><function>ext:with-local-interrupts</function> executes its
+ body with interrupts enabled provided that for there is an
+ <function>ext:allow-with-interrupts</function> for every
+ <function>ext:without-interrupts</function> surrounding the current
+ one. <function>ext:with-local-interrupts</function> is equivalent
+ to:</para>
+<programlisting>
+ (allow-with-interrupts (with-interrupts ...))
+</programlisting>
+
+ <para>Care must be taken not to let either
+ <function>ext:allow-with-interrupts</function> or
+ <function>ext:with-local-interrupts</function> appear in a function
+ that escapes from inside the
+ <function>ext:without-interrupts</function> in:</para>
+<programlisting>
+ (without-interrupts
+ ;; The body of the lambda would be executed with WITH-INTERRUPTS allowed
+ ;; regardless of the interrupt policy in effect when it is called.
+ (lambda () (allow-with-interrupts ...)))
+
+ (without-interrupts
+ ;; The body of the lambda would be executed with interrupts enabled
+ ;; regardless of the interrupt policy in effect when it is called.
+ (lambda () (with-local-interrupts ...)))
+</programlisting>
+ </refsect1>
+</refentry>
+</section>
+</chapter>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+ -->
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
+ <uri resource="asdf.xmlf" typeId="DocBook5"/>
+ <uri resource="bibliography.xmlf" typeId="DocBook5"/>
+ <uri resource="clos.xmlf" typeId="DocBook5"/>
+ <uri resource="compiler.xmlf" typeId="DocBook5"/>
+ <uri resource="copyright.xmlf" typeId="DocBook5"/>
+ <uri resource="declarations.xmlf" typeId="DocBook5"/>
+ <uri resource="discarded.xmlf" typeId="DocBook5"/>
+ <uri resource="ecldev.xmlf" typeId="DocBook5"/>
+ <uri resource="embed.xmlf" typeId="DocBook5"/>
+ <uri resource="ffi.xmlf" typeId="DocBook5"/>
+ <uri resource="gc.xmlf" typeId="DocBook5"/>
+ <uri resource="internals.xmlf" typeId="DocBook5"/>
+ <uri resource="interpreter.xmlf" typeId="DocBook5"/>
+ <uri resource="intro.xmlf" typeId="DocBook5"/>
+ <uri resource="io.xmlf" typeId="DocBook5"/>
+ <uri resource="macros.xmlf" typeId="DocBook5"/>
+ <uri resource="memory.xmlf" typeId="DocBook5"/>
+ <uri resource="mop.xmlf" typeId="DocBook5"/>
+ <uri resource="mp.xmlf" typeId="DocBook5"/>
+ <uri resource="os.xmlf" typeId="DocBook5"/>
+ <uri resource="pde.xmlf" typeId="DocBook5"/>
+ <uri resource="preface.xmlf" typeId="DocBook5"/>
+ <uri resource="ref_embed.xmlf" typeId="DocBook5"/>
+ <uri resource="ref_memory.xmlf" typeId="DocBook5"/>
+ <uri resource="ref_mp.xmlf" typeId="DocBook5"/>
+ <uri resource="ref_os.xmlf" typeId="DocBook5"/>
+ <uri resource="ref_signals.xmlf" typeId="DocBook5"/>
+ <uri resource="signals.xmlf" typeId="DocBook5"/>
+ <uri resource="standards.xmlf" typeId="DocBook5"/>
+ <uri resource="ecl.xml" typeId="DocBook5"/>
+ <uri resource="uffi/ref_aggregate.xml" typeId="DocBook5"/>
+ <uri resource="uffi/ref_declare.xml" typeId="DocBook5"/>
+ <uri resource="uffi/ref_func_libr.xml" typeId="DocBook5"/>
+ <uri resource="uffi/ref_object.xml" typeId="DocBook5"/>
+ <uri resource="uffi/ref_primitive.xml" typeId="DocBook5"/>
+ <uri resource="uffi/ref_string.xml" typeId="DocBook5"/>
+ <uri pattern="*.xmlf" typeId="DocBook5"/>
+ <typeId id="DocBook5" uri="/usr/local/Cellar/docbook/5.0/docbook/xml/5.0/rng/docbookxi.rnc"/>
+ <namespace ns="http://docbook.org/ns/docbook" uri="/usr/local/Cellar/docbook/5.0/docbook/xml/5.0/rng/docbookxi.rnc"/>
+</locatingRules>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xml:id="ext.signals">
+ <title>Signals and interrupts</title>
+
+ <section xml:id="ext.signals.intro">
+ <title>Problems associated to signals</title>
+
+ <para>POSIX contemplates the notion of "signals", which are events that
+ cause a process or a thread to be interrupted. Windows uses the term
+ "exception", which includes also a more general kind of errors.</para>
+
+ <para>In both cases the consequence is that a thread or process may be
+ interrupted at any time, either by causes which are intrinsic to them
+ (synchronous signals), such as floating point exceptions, or extrinsic
+ (asynchronous signals), such as the process being aborted by the
+ user.</para>
+
+ <para>Of course, those interruptions are not always welcome. When the
+ interrupt is delivered and a handler is invoked, the thread or even the
+ whole program may be in an inconsistent state. For instance the thread may
+ have acquired a lock, or it may be in the process of filling the fields of
+ a structure. Furthermore, sometimes the signal that a process receives may
+ not even be related to it, as in the case when a user presses Cltr-C
+ and a SIGINT signal is delivered to an arbitrary thread, or when the
+ process receives the Windows exception CTRL_CLOSE_EVENT denoting
+ that the terminal window is being closed.</para>
+
+ <para>Understanding this, POSIX restricts severely what functions can be
+ called from a signal handler, thereby limiting its usefulness. However,
+ Common Lisp users expect to be able to handle floating point exceptions and
+ to gracefully manage user interrupts, program exits, etc. In an attempt to
+ solve this seemingly impossible problem, &ECL; has taken a pragmatic
+ approach that works, it is rather safe, but involves some work on the &ECL;
+ maintainers and also on users that want to embed &ECL; as a library.</para>
+ </section>
+
+ <section xml:id="ext.signals.kinds">
+ <title>Kinds of signals</title>
+
+ <section xml:id="ext.signals.synchronous">
+ <title>Synchronous signals</title>
+
+ <para>The name derives from POSIX and it denotes interrupts that occur due
+ to the code that a particular thread executes. They are largely equivalent
+ to C++ and Java exceptions, and in Windows they are called "unchecked
+ exceptions."</para>
+
+ <para>Common Lisp programs may generate mostly three kinds of synchronous
+ signals:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Floating point exceptions, that result from overflows in
+ computations, division by zero, and so on.</para>
+ </listitem>
+ <listitem>
+ <para>Access violations, such as dereferencing NULL pointers,
+ writing into regions of memory that are protected, etc.</para>
+ </listitem>
+ <listitem>
+ <para>Process interrupts.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The first family of signals are generated by the floating point
+ processing hardware in the computer, and they typically happen when code
+ is compiled with low security settings, performing mathematical operations
+ without checks.</para>
+
+ <para>The second family of signals may seem rare, but unfortunately they
+ still happen quite often. One scenario is wrong code that handles memory
+ directly via FFI. Another one is undetected stack overflows, which typically
+ result in access to protected memory regions. Finally, a very common cause
+ of these kind of exceptions is invoking a function that has been compiled
+ with very low security settings with arguments that are not of the expected
+ type -- for instance, passing a float when a structure is expected.</para>
+
+ <para>The third family is related to the multiprocessing capabilities in
+ Common Lisp systems and more precisely to the <xref
+ linkend="ref.mp.interrupt-process"/> function which is used to kill,
+ interrupt and inspect arbitrary threads. In POSIX systems &ECL; informs a
+ given thread about the need to interrupt its execution by sending a
+ particular signal from the set which is available to the user.</para>
+
+ <para>Note that in neither of these cases we should let the signal pass
+ unnoticed. Access violations and floating point exceptions may propagate
+ through the program causing more harm than expected, and without
+ process interrupts we will not be able to stop and cancel different
+ threads. The only question that remains, though, is whether such signals can
+ be handled by the thread in which they were generated and how.</para>
+ </section>
+
+ <section xml:id="ext.signals.asynchronous">
+ <title>Asynchronous signals</title>
+
+ <para>In addition to the set of synchronous signals or "exceptions", we
+ have a set of signals that denote "events", things that happen while the
+ program is being executed, and "requests". Some typical examples are:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Request for program termination (SIGKILL, SIGTERM).</para>
+ </listitem>
+ <listitem>
+ <para>Indication that a child process has finished.</para>
+ </listitem>
+ <listitem>
+ <para>Request for program interruption (SIGINT), typically as a
+ consecuence of pressing a key combination, Ctrl-C.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The important difference with synchronous signals is that we have no
+ thread that causes the interrupt and thus there is no preferred way of
+ handling them. Moreover, the operating system will typically dispatch these
+ signals to an arbitrary thread, unless we set up mechanisms to prevent
+ it. This can have nasty consequences if the incoming signal interrupt a
+ system call, or leaves the interrupted thread in an inconsistent
+ state.</para>
+ </section>
+ </section>
+
+ <section xml:id="ext.signals.implementation">
+ <title>Signals and interrupts in &ECL;</title>
+
+ <para>The signal handling facilities in &ECL; are constrained by two
+ needs. First of all, we can not ignore the synchronous signals mentioned in
+ <xref linkend="ext.signals.synchronous"/>. Second, all other signals should
+ cause the least harm to the running threads. Third, when a signal is handled
+ synchronously using a signal handler, the handler should do almost nothing
+ unless we are completely sure that we are in an interruptible region, that is
+ outside system calls, in code that &ECL; knows and controls.</para>
+
+ <para>The way in which this is solved is based on the existence of both
+ synchronous and asynchronous signal handling code, as explained in the
+ following two sections.</para>
+
+ <section xml:id="ext.signals.asynchronous-handler">
+ <title>Handling of asynchronous signals</title>
+
+ <para>In systems in which this is possible, &ECL; creates a signal handling
+ thread to detect and process asynchronous signals (See <xref
+ linkend="ext.signals.asynchronous"/>). This thread is a trivial one and does
+ not process the signals itself: it communicates with, or launches new signal
+ handling threads to act accordingly to the denoted events.</para>
+
+ <para>The use of a separate thread has some nice consequences. The first
+ one is that those signals will not interrupt any sensitive code. The
+ second one is that the signal handling thread will be able to execute
+ arbitrary lisp or C code, since it is not being executed in a sensitive
+ context. Most important, this style of signal handling is the recommended
+ one by the POSIX standards, and it is the one that Windows uses.</para>
+
+ <para>The installation of the signal handling thread is dictated by a boot
+ time option, <varname>ECL_OPT_SIGNAL_HANDLING_THREAD</varname>, and it will
+ only be possible in systems that support either POSIX or Windows
+ threads.</para>
+
+ <para>Systems which embed &ECL; as an extension language may wish to
+ deactivate the signal handling thread using the previously mentioned
+ option. If this is the case, then they should take appropriate measures to
+ avoid interrupting the code in &ECL; when such signals are delivered.</para>
+
+ <para>Systems which embed &ECL; and do not mind having a separate signal
+ handling thread can control the set of asynchronous signals which is handled
+ by this thread. This is done again using the appropriate boot options such
+ as <varname>ECL_OPT_TRAP_SIGINT</varname>,
+ <varname>ECL_OPT_TRAP_SIGTERM</varname>, etc. Note that in order to detect
+ and handle those signals, &ECL; must block them from delivery to any other
+ thread. This means changing the <function>sigprocmask()</function> in POSIX
+ systems or setting up a custom <function>SetConsoleCtrlHandler()</function>
+ in Windows.</para>
+ </section>
+
+ <section xml:id="ext.signals.synchronous-handler">
+ <title>Handling of synchronous signals</title>
+
+ <para>We have already mentioned that certain synchronous signals and
+ exceptions can not be ignored and yet the corresponding signal handlers are
+ not able to execute arbitrary code. To solve this seemingly impossible
+ contradiction, &ECL; uses a simple solution, which is to mark the sections of
+ code which are interruptible, and in which it is safe for the handler to run
+ arbitrary code. All other regions would be considered "unsafe" and would be
+ protected from signals and exceptions.</para>
+
+ <para>In principle this "marking" of safe areas can be done using POSIX
+ functions such as <function>pthread_sigmask()</function> or
+ <function>sigprocmask()</function>. However in practice this is slow, as it
+ involves at least a function call, resolving thread-local variables, etc,
+ etc, and it will not work in Windows.</para>
+
+ <para>Furthermore, sometimes we want signals to be detected but not to be
+ immediately processed. For instance, when reading from the terminal we want
+ to be able to interrupt the process, but we can not execute the code from
+ the handler, since the C function which is used to read from the terminal,
+ <function>read()</function>, may have left the input stream in an
+ inconsistent, or even locked state.</para>
+
+ <para>The approach in &ECL; is more lightweight: we install our own signal
+ handler and use a thread-local variable as a flag that determines whether
+ the thread is executing interrupt safe code or not. More precisely, if the
+ variable <code>ecl_process_env()->disable_interrupts</code> is set, signals
+ and exceptions will be postponed and then the information about the signal
+ is queued. Otherwise the appropriate code is executed: for instance invoking
+ the debugger, jumping to a condition handler, quitting, etc.</para>
+
+ <para>Systems that embed &ECL; may wish to deactivate completely these
+ signal handlers. This is done using the boot options,
+ <varname>ECL_OPT_TRAP_SIGFPE</varname>,
+ <varname>ECL_OPT_TRAP_SIGSEGV</varname>,
+ <varname>ECL_OPT_TRAP_SIGBUS</varname>,
+ <varname>ECL_OPT_TRAP_INTERRUPT_SIGNAL</varname>.</para>
+
+ <para>Systems that embed &ECL; and want to allow handling of synchronous
+ signals should take care to also trap the associated lisp conditions that
+ may arise. This is automatically taken care of by functions such as
+ <function>si_safe_eval()</function>, and in all other cases it can be solved
+ by enclosing the unsafe code in a <function>CL_CATCH_ALL_BEGIN</function>
+ frame (See <xref linkend="ref.embed.cl_catch_all"/>).</para>
+ </section>
+ </section>
+
+ <section xml:id="ext.signals.embedding">
+ <title>Considerations when embedding &ECL;</title>
+
+ <para>There are several approaches when handling signals and interrupts in
+ a program that uses &ECL;. One is to install your own signal handlers. This
+ is perfectly fine, but you should respect the same restrictions as &ECL;.
+ Namely, you may not execute arbitrary code from those signal handlers, and
+ in particular it will not always be safe to execute Common Lisp code from
+ there.</para>
+
+ <para>If you want to use your own signal handlers then you should set the
+ appropriate options before invoking <function>cl_boot()</function>, as
+ explained in <xref linkend="ref.embed.ecl_set_option"/>. Note that in this
+ case &ECL; will not always be able to detect floating point exceptions,
+ specially if your compiler does not support C99 and the corresponding
+ floating point flags.</para>
+
+ <para>The other option is to let &ECL; handle signals itself. This would be
+ safer when the dominant part of the code is Common Lisp, but you may need
+ to protect the code that embeds &ECL; from being interrupted using either
+ the macros <xref linkend="ref.embed.ecl_disable_interrupts"/> and <xref
+ linkend="ref.embed.ecl_enable_interrupts"/> or the POSIX functions
+ <function>pthread_sigmaks</function> and
+ <function>sigprocmask</function>.</para>
+ </section>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ref_signals.xmlf" xpointer="ext.signals.dict"/>
+
+</chapter>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-parent-document: "ecl.xml"
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 1
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "../ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <reference xml:id="uffi.aggregates">
+ <title>Aggregate Types</title>
+ <partintro>
+ <title>Overview</title>
+ <para>
+ Aggregate types are comprised of one or more primitive types.
+ </para>
+ </partintro>
+
+ <refentry xml:id="uffi.def-enum">
+ <refnamediv>
+ <refname><function>def-enum</function></refname>
+ <refpurpose>Defines a &C; enumeration.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>def-enum</function> <replaceable>name fields &key separator-string</replaceable>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <para>A symbol that names the enumeration.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>fields</parameter></term>
+ <listitem>
+ <para>A list of field defintions. Each definition can be
+ a symbol or a list of two elements. Symbols get assigned a value of the
+ current counter which starts at <computeroutput>0</computeroutput> and
+ increments by <computeroutput>1</computeroutput> for each subsequent symbol. It the field definition is a list, the first position is the symbol and the second
+ position is the value to assign the the symbol. The current counter gets set
+ to <computeroutput>1+</computeroutput> this value.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>separator-string</parameter></term>
+ <listitem>
+ <para>A string that governs the creation of constants. The
+ default is <computeroutput>"#"</computeroutput>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Declares a &C; enumeration. It generates constants with integer values for the elements of the enumeration. The symbols for the these constant
+ values are created by the <function>concatenation</function> of the
+ enumeration name, separator-string, and field symbol. Also creates
+ a foreign type with the name <parameter>name</parameter> of type
+ <constant>:int</constant>.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(def-enum abc (:a :b :c))
+;; Creates constants abc#a (1), abc#b (2), abc#c (3) and defines
+;; the foreign type "abc" to be :int
+
+(def-enum efoo (:e1 (:e2 10) :e3) :separator-string "-")
+;; Creates constants efoo-e1 (1), efoo-e2 (10), efoo-e3 (11) and defines
+;; the foreign type efoo to be :int</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>Creates a :int foreign type, defines constants.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.def-struct">
+ <refnamediv>
+ <refname><function>def-struct</function></refname>
+ <refpurpose>Defines a &C; structure.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>def-struct</function> <replaceable>name &rest fields</replaceable>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <para>A symbol that names the structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>fields</parameter></term>
+ <listitem>
+ <para>A variable number of field defintions. Each definition is a list consisting of a symbol naming the field followed by its foreign type.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Declares a structure. A special type is available as a slot
+ in the field. It is a pointer that points to an instance of the parent
+ structure. It's type is <constant>:pointer-self</constant>.
+
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(def-struct foo (a :unsigned-int)
+ (b (* :char))
+ (c (:array :int 10))
+ (next :pointer-self))</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>Creates a foreign type.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.get-slot-value">
+ <refnamediv>
+ <refname><function>get-slot-value</function></refname>
+ <refpurpose>Retrieves a value from a slot of a structure.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>get-slot-value</function> <replaceable>obj type field</replaceable> => <returnvalue>value</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>obj</parameter></term>
+ <listitem>
+ <para>A pointer to foreign structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>A name of the foreign structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>field</parameter></term>
+ <listitem>
+ <para>A name of the desired field in foreign structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>value</returnvalue></term>
+ <listitem>
+ <para>The value of the field in the structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Accesses a slot value from a structure. This is generalized
+ and can be used with <function>setf</function>.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(get-slot-value foo-ptr 'foo-structure 'field-name)
+(setf (get-slot-value foo-ptr 'foo-structure 'field-name) 10)</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.get-slot-pointer">
+ <refnamediv>
+ <refname><function>get-slot-pointer</function></refname>
+ <refpurpose>Retrieves a pointer from a slot of a structure.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>get-slot-pointer</function> <replaceable>obj type field</replaceable> => <returnvalue>pointer</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>obj</parameter></term>
+ <listitem>
+ <para>A pointer to foreign structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>A name of the foreign structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>field</parameter></term>
+ <listitem>
+ <para>A name of the desired field in foreign structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>pointer</returnvalue></term>
+ <listitem>
+ <para>The value of the field in the structure.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ This is similar to <function>get-slot-value</function>. It
+ is used when the value of a slot is a pointer type.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(get-slot-pointer foo-ptr 'foo-structure 'my-char-ptr)</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.def-array-pointer">
+ <refnamediv>
+ <refname><function>def-array-pointer</function></refname>
+ <refpurpose>Defines a pointer to a array of type.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>def-array-pointer</function> <replaceable>name type</replaceable>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <para>A name of the new foreign type.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>The foreign type of the array elements.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Defines a type tat is a pointer to an array of type.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(def-array-pointer byte-array-pointer :unsigned-char)</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>Defines a new foreign type.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.deref-array">
+ <refnamediv>
+ <refname><function>deref-array</function></refname>
+ <refpurpose>Deference an array.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>deref-array</function> <replaceable>array type position</replaceable> => <returnvalue>value</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>array</parameter></term>
+ <listitem>
+ <para>A foreign array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>The foreign type of the array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>position</parameter></term>
+ <listitem>
+ <para>An integer specifying the position to retrieve from
+ the array.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>value</returnvalue></term>
+ <listitem>
+ <para>The value stored in the position of the array.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Dereferences (retrieves) the value of an array element.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(def-array-pointer ca :char)
+ (let ((fs (convert-to-foreign-string "ab")))
+ (values (null-char-p (deref-array fs 'ca 0))
+ (null-char-p (deref-array fs 'ca 2))))
+=> &nil;
+ &t;</screen>
+ </refsect1>
+ <refsect1>
+ <title>Notes</title>
+ <para>
+ The TYPE argument is ignored for CL implementations other than
+ AllegroCL. If you want to cast a pointer to another type use
+ WITH-CAST-POINTER together with DEREF-POINTER/DEREF-ARRAY.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.def-union">
+ <refnamediv>
+ <refname><function>def-union</function></refname>
+ <refpurpose>Defines a foreign union type.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>def-union</function> <replaceable>name &rest fields</replaceable>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <para>A name of the new union type.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>fields</parameter></term>
+ <listitem>
+ <para>A list of fields of the union.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Defines a foreign union type.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(def-union test-union
+ (a-char :char)
+ (an-int :int))
+
+(let ((u (allocate-foreign-object 'test-union)))
+ (setf (get-slot-value u 'test-union 'an-int) (+ 65 (* 66 256)))
+ (prog1
+ (ensure-char-character (get-slot-value u 'test-union 'a-char))
+ (free-foreign-object u)))
+=> #\A</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>Defines a new foreign type.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ </reference>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 0
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "../ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <reference xml:id="uffi.ref_declarations">
+ <title>Declarations</title>
+
+ <partintro>
+ <sect1>
+ <title>Overview</title>
+ <para>Declarations are used to give the compiler optimizing
+ information about foreign types. Currently, only &CMUCL;
+ supports declarations. On &ACL; and &LW;, these expressions
+ declare the type generically as &t;
+ </para>
+ </sect1>
+ </partintro>
+
+ <refentry xml:id="uffi.def-type">
+ <refnamediv>
+ <refname>def-type</refname>
+ <refpurpose>Defines a Common Lisp type.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>def-type</function> <replaceable>name type</replaceable>
+ </synopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <para>A symbol naming the type</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>A form that specifies the &UFFI; type. It is not evaluated.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Description</title>
+ <para>Defines a Common Lisp type based on a &UFFI; type.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(def-type char-ptr '(* :char))
+ ...
+(defun foo (ptr)
+ (declare (type char-ptr ptr))
+ ...
+ </screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>Defines a new &CommonLisp; type.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+ </reference>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 0
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "../ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <reference xml:id="uffi.func_libr">
+ <title>Functions & Libraries</title>
+
+ <refentry xml:id="uffi.def-function">
+ <refnamediv>
+ <refname><function>def-function</function></refname>
+ <refpurpose>Declares a function.
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <synopsis>
+ <function>def-function</function> <replaceable>name args &key module returning</replaceable>
+ </synopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <para>A string or list specificying the function name. If it is a string, that names the foreign function. A Lisp name is created by translating #\_ to #\- and by converting to upper-case in case-insensitive Lisp implementations. If it is a list, the first item is a string specifying the foreign function name and the second it is a symbol stating the Lisp name.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem>
+ <para>A list of argument declarations. If &nil;, indicates that the function does not take any arguments.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>module</parameter></term>
+ <listitem>
+ <para>A string specifying which module (or library) that the foreign function resides. (Required by Lispworks)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>returning</returnvalue></term>
+ <listitem>
+ <para>A declaration specifying the result type of the
+ foreign function. If <constant>:void</constant> indicates module does not return any value.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>Declares a foreign function.</para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <programlisting>
+(def-function "gethostname"
+ ((name (* :unsigned-char))
+ (len :int))
+ :returning :int)
+ </programlisting>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.load-foreign-library">
+ <refnamediv>
+ <refname><function>load-foreign-library</function></refname>
+ <refpurpose>Loads a foreign library.
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Function</title>
+ <synopsis>
+ <function>load-foreign-library</function> <replaceable>filename &key module supporting-libraries force-load</replaceable> => <returnvalue>success</returnvalue>
+ </synopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>filename</parameter></term>
+ <listitem>
+ <para>A string or pathname specifying the library location
+ in the filesystem. At least one implementation (&LW;) can not
+ accept a logical pathname. If this parameter denotes a pathname without a
+ directory component then most of the supported Lisp implementations will be
+ able to find the library themselves if it is located in one of the standard
+ locations as defined by the underlying operating system.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>module</parameter></term>
+ <listitem>
+ <para>A string designating the name of the module to apply
+ to functions in this library. (Required for Lispworks)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>supporting-libraries</parameter></term>
+ <listitem>
+ <para>A list of strings naming the libraries required to
+ link the foreign library. (Required by CMUCL)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>force-load</parameter></term>
+ <listitem>
+ <para>Forces the loading of the library if it has been previously loaded. </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>success</returnvalue></term>
+ <listitem>
+ <para>A boolean flag, &t; if the library was able to be
+ loaded successfully or if the library has been previously loaded,
+ otherwise &nil;.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>Loads a foreign library. Applies a module name to functions
+ within the library. Ensures that a library is only loaded once during
+ a session. A library can be reloaded by using the <symbol>:force-load</symbol> key.</para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(load-foreign-library #p"/usr/lib/libmysqlclient.so"
+ :module "mysql"
+ :supporting-libraries '("c"))
+=> T</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>Loads the foreign code into the Lisp system.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>Ability to load the file.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.find-foreign-library">
+ <refnamediv>
+ <refname><function>find-foreign-library</function></refname>
+ <refpurpose>Finds a foreign library file.
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Function</title>
+ <synopsis>
+ <function>find-foreign-library</function> <replaceable>names directories & drive-letters types</replaceable> => <returnvalue>path</returnvalue>
+ </synopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>names</parameter></term>
+ <listitem>
+ <para>A string or list of strings containing the base name of the
+ library file.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>directories</parameter></term>
+ <listitem>
+ <para>A string or list of strings containing the directory the library file.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>drive-letters</parameter></term>
+ <listitem>
+ <para>A string or list of strings containing the drive letters for the library file.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>types</parameter></term>
+ <listitem>
+ <para>A string or list of strings containing the file type of the library file. Default
+ is &nil;. If &nil;, will use a default type based on the currently running implementation.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>path</returnvalue></term>
+ <listitem>
+ <para>A path containing the path found, or &nil; if the library file was not found.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>Finds a foreign library by searching through a number of possible locations. Returns
+ the path of the first found file.</para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(find-foreign-library '("libmysqlclient" "libmysql")
+ '("/opt/mysql/lib/mysql/" "/usr/local/lib/" "/usr/lib/" "/mysql/lib/opt/")
+ :types '("so" "dll")
+ :drive-letters '("C" "D" "E"))
+=> #P"D:\\mysql\\lib\\opt\\libmysql.dll"
+ </screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ </reference>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 0
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "../ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <reference xml:id="uffi.objects">
+ <title>Objects</title>
+ <partintro>
+ <title>Overview</title>
+ <para>
+ Objects are entities that can allocated, referred to by pointers, and
+ can be freed.</para>
+ </partintro>
+
+
+ <refentry xml:id="uffi.allocate-foreign-object">
+ <refnamediv>
+ <refname><function>allocate-foreign-object</function></refname>
+ <refpurpose>Allocates an instance of a foreign object.
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>allocate-foreign-object</funcdef>
+ <paramdef><parameter>type</parameter></paramdef>
+ <paramdef>&optional;</paramdef>
+ <paramdef><parameter>size</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>The type of foreign object to allocate. This parameter is evaluated.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>size</parameter></term>
+ <listitem>
+ <para>An optional size parameter that is evaluated. If specified, allocates and returns an
+ array of <parameter>type</parameter> that is <parameter>size</parameter> members long. This parameter is evaluated.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem>
+ <para>A pointer to the foreign object.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>Allocates an instance of a foreign object. It returns a pointer to
+ the object.</para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(def-struct ab (a :int) (b :double))
+ (allocate-foreign-object 'ab)
+=> #<ptr></screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.free-foreign-object">
+ <refnamediv>
+ <refname><function>free-foreign-object</function></refname>
+ <refpurpose>Frees memory that was allocated for a foreign boject.
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>free-foreign-object</funcdef>
+ <paramdef><parameter>ptr</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>ptr</parameter></term>
+ <listitem>
+ <para>A pointer to the allocated foreign object to free.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Frees the memory used by the allocation of a foreign object.</para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.with-foreign-object">
+ <refnamediv>
+ <refname><function>with-foreign-object</function></refname>
+ <refpurpose>Wraps the allocation of a foreign object around a body of code.
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>with-foreign-object</funcdef>
+ <paramdef><parameter>(var type)</parameter></paramdef>
+ <paramdef><parameter>&body;</parameter></paramdef>
+ <paramdef><parameter>body</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>var</parameter></term>
+ <listitem>
+ <para>The variable name to bind.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>The type of foreign object to allocate. This parameter is evaluated.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem>
+ <para>The result of evaluating the <parameter>body</parameter>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title> <para> This function wraps the allocation,
+ binding, and destruction of a foreign object. On &CMUCL; and &LW;
+ platforms the object is stack allocated for efficiency. Benchmarks show
+ that &ACL; performs much better with static allocation.</para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+ (defun gethostname2 ()
+ "Returns the hostname"
+ (uffi:with-foreign-object (name '(:array :unsigned-char 256))
+ (if (zerop (c-gethostname (uffi:char-array-to-pointer name) 256))
+ (uffi:convert-from-foreign-string name)
+ (error "gethostname() failed."))))</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.size-of-foreign-type">
+ <refnamediv>
+ <refname><function>size-of-foreign-type</function></refname>
+ <refpurpose>Returns the number of data bytes used by a foreign object type.
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>size-of-foreign-type</funcdef>
+ <paramdef><parameter>ftype</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>ftype</parameter></term>
+ <listitem>
+ <para>A foreign type specifier. This parameter is evaluated.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Returns the number of data bytes used by a foreign object type. This does not include any Lisp storage overhead.</para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <para>
+ <screen>
+ (size-of-foreign-object :unsigned-byte)
+ => 1
+ (size-of-foreign-object 'my-100-byte-vector-type)
+ => 100</screen></para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1> <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.pointer-address">
+ <refnamediv>
+ <refname><function>pointer-address</function></refname>
+ <refpurpose>Returns the address of a pointer.
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>pointer-address</funcdef>
+ <paramdef><parameter>ptr</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>ptr</parameter></term>
+ <listitem>
+ <para>A pointer to a foreign object.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem>
+ <para>An integer representing the pointer's address.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Returns the address as an integer of a pointer.</para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.deref-pointer">
+ <refnamediv>
+ <refname><function>deref-pointer</function></refname>
+ <refpurpose>Deferences a pointer.
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>deref-pointer</funcdef>
+ <paramdef><parameter>ptr</parameter></paramdef>
+ <paramdef><parameter>type</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>ptr</parameter></term>
+ <listitem>
+ <para>A pointer to a foreign object.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>A foreign type of the object being pointed to.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem>
+ <para>The value of the object where the pointer points.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Returns the object to which a pointer points.</para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <para>
+ <screen>
+ (let ((intp (allocate-foreign-object :int)))
+ (setf (deref-pointer intp :int) 10)
+ (prog1
+ (deref-pointer intp :int)
+ (free-foreign-object intp)))
+ => 10</screen></para>
+ </refsect1>
+ <refsect1>
+ <title>Notes</title>
+ <para>
+ The TYPE argument is ignored for CL implementations other than
+ AllegroCL. If you want to cast a pointer to another type use
+ WITH-CAST-POINTER together with DEREF-POINTER/DEREF-ARRAY.</para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.ensure-char-character">
+ <refnamediv>
+ <refname><function>ensure-char-character</function></refname>
+ <refpurpose>Ensures that a dereferenced <constant>:char</constant> pointer is
+ a character.
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ensure-char-character</funcdef>
+ <paramdef><parameter>object</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>object</parameter></term>
+ <listitem>
+ <para>Either a character or a integer specifying a character code.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem>
+ <para>A character.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Ensures that an objects obtained by dereferencing
+ <constant>:char</constant> and <constant>:unsigned-char</constant>
+ pointers are a lisp character.</para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <para>
+ <screen>
+ (let ((fs (convert-to-foreign-string "a")))
+ (prog1
+ (ensure-char-character (deref-pointer fs :char))
+ (free-foreign-object fs)))
+ => #\a</screen></para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>Depending upon the implementation and what &UFFI; expects, this
+ macro may signal an error if the object is not a character or
+ integer.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.ensure-char-integer">
+ <refnamediv>
+ <refname><function>ensure-char-integer</function></refname>
+ <refpurpose>Ensures that a dereferenced <constant>:char</constant> pointer is
+ an integer.
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>ensure-char-integer</funcdef>
+ <paramdef><parameter>object</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>object</parameter></term>
+ <listitem>
+ <para>Either a character or a integer specifying a character code.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem>
+ <para>An integer.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Ensures that an object obtained by dereferencing a
+ <constant>:char</constant> pointer is an integer.</para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <para>
+ <screen>
+ (let ((fs (convert-to-foreign-string "a")))
+ (prog1
+ (ensure-char-integer (deref-pointer fs :char))
+ (free-foreign-object fs)))
+ => 96</screen></para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>Depending upon the implementation and what &UFFI; expects, this
+ macro may signal an error if the object is not a character or
+ integer.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.make-null-pointer">
+ <refnamediv>
+ <refname><function>make-null-pointer</function></refname>
+ <refpurpose>Create a &NULL; pointer.
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>make-null-pointer</funcdef>
+ <paramdef><parameter>type</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>A type of object to which the pointer refers.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem>
+ <para>The &NULL; pointer of type <parameter>type</parameter>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Creates a &NULL; pointer of a specified type.</para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.null-pointer-p">
+ <refnamediv>
+ <refname><function>null-pointer-p</function></refname>
+ <refpurpose>Tests a pointer for &NULL; value.
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>null-pointer-p</funcdef>
+ <paramdef><parameter>ptr</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>ptr</parameter></term>
+ <listitem>
+ <para>A foreign object pointer.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem>
+ <para>The boolean flag.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ A predicate testing if a pointer is has a &NULL; value.</para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.null-cstring-pointer">
+ <refnamediv>
+ <refname><varname>+null-cstring-pointer+</varname></refname>
+ <refpurpose>A constant &NULL; cstring pointer.
+ </refpurpose>
+ <refclass>Constant</refclass>
+ </refnamediv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ A &NULL; cstring pointer. This can be used for testing
+ if a cstring returned by a function is &NULL;.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.with-cast-pointer">
+ <refnamediv>
+ <refname><function>with-cast-pointer</function></refname>
+ <refpurpose>Wraps a body of code with a pointer cast to a new type.
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>with-cast-pointer</funcdef>
+ <paramdef>(<parameter>binding-name ptr type</parameter>)</paramdef>
+ <paramdef>&body;</paramdef>
+ <paramdef><parameter>body</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>binding-name</parameter></term>
+ <listitem>
+ <para>A symbol which will be bound to the casted object.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>ptr</parameter></term>
+ <listitem>
+ <para>A pointer to a foreign object.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>A foreign type of the object being pointed to.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem>
+ <para>The value of the object where the pointer points.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Executes BODY with POINTER cast to be a pointer to type TYPE.
+ BINDING-NAME is will be bound to this value during the execution of
+ BODY.
+
+ This is a no-op in AllegroCL but will wrap BODY in a LET form if
+ BINDING-NAME is provided.
+
+ This macro is meant to be used in conjunction with DEREF-POINTER or
+ DEREF-ARRAY. In Allegro CL the "cast" will actually take place in
+ DEREF-POINTER or DEREF-ARRAY.</para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+ (with-foreign-object (size :int)
+ ;; FOO is a foreign function returning a :POINTER-VOID
+ (let ((memory (foo size)))
+ (when (mumble)
+ ;; at this point we know for some reason that MEMORY points
+ ;; to an array of unsigned bytes
+ (with-cast-pointer (memory :unsigned-byte)
+ (dotimes (i (deref-pointer size :int))
+ (do-something-with
+ (deref-array memory '(:array :unsigned-byte) i)))))))</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.def-foreign-var">
+ <refnamediv>
+ <refname><function>def-foreign-var</function></refname>
+ <refpurpose>
+ Defines a symbol macro to access a variable in foreign code
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>def-foreign-var</funcdef>
+ <paramdef><parameter>name</parameter></paramdef>
+ <paramdef><parameter>type</parameter></paramdef>
+ <paramdef><parameter>module</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <para>
+ A string or list specificying the symbol macro's name. If it is a
+ string, that names the foreign variable. A Lisp name is created
+ by translating #\_ to #\- and by converting to upper-case in
+ case-insensitive Lisp implementations. If it is a list, the first
+ item is a string specifying the foreign variable name and the
+ second it is a symbol stating the Lisp name.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <para>A foreign type of the foreign variable.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>module</returnvalue></term>
+ <listitem>
+ <para>
+ A string specifying the module (or library) the foreign variable
+ resides in. (Required by Lispworks)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Defines a symbol macro which can be used to access (get and set) the
+ value of a variable in foreign code.</para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <refsect2>
+ <title>C code</title>
+ <screen>
+ int baz = 3;
+
+ typedef struct {
+ int x;
+ double y;
+ } foo_struct;
+
+ foo_struct the_struct = { 42, 3.2 };
+
+ int foo () {
+ return baz;
+ }</screen>
+ </refsect2>
+ <refsect2>
+ <title>Lisp code</title>
+ <screen>
+ (uffi:def-struct foo-struct
+ (x :int)
+ (y :double))
+
+ (uffi:def-function ("foo" foo)
+ ()
+ :returning :int
+ :module "foo")
+
+ (uffi:def-foreign-var ("baz" *baz*) :int "foo")
+ (uffi:def-foreign-var ("the_struct" *the-struct*) foo-struct "foo")
+
+
+ *baz*
+ => 3
+
+ (incf *baz*)
+ => 4
+
+ (foo)
+ => 4</screen>
+ </refsect2>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ </reference>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 0
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "../ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <reference xml:id="uffi.primitives">
+ <title>Primitive Types</title>
+ <partintro>
+ <title>Overview</title>
+ <para>
+ Primitive types have a single value, these include
+ characters, numbers, and pointers. They are all symbols in
+ the keyword package.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><constant>:char</constant> - Signed 8-bits. A
+ dereferenced :char pointer returns an character.
+ </para>
+ </listitem>
+ <listitem>
+ <para><constant>:unsigned-char</constant> - Unsigned 8-bits. A dereferenced :unsigned-char
+ pointer returns an character.
+ </para>
+ </listitem>
+ <listitem>
+ <para><constant>:byte</constant> - Signed 8-bits. A
+ dereferenced :byte pointer returns an integer.
+ </para>
+ </listitem>
+ <listitem>
+ <para><constant>:unsigned-byte</constant> - Unsigned 8-bits. A
+ dereferenced :unsigned-byte pointer returns an integer.
+ </para>
+ </listitem>
+ <listitem>
+ <para><constant>:short</constant> - Signed 16-bits.
+ </para>
+ </listitem>
+ <listitem>
+ <para><constant>:unsigned-short</constant> - Unsigned 16-bits.
+ </para>
+ </listitem>
+ <listitem>
+ <para><constant>:int</constant> - Signed 32-bits.</para>
+ </listitem>
+ <listitem>
+ <para><constant>:unsigned-int</constant> - Unsigned 32-bits.</para>
+ </listitem>
+ <listitem>
+ <para><constant>:long</constant> - Signed 32 or 64 bits, depending upon the platform.</para>
+ </listitem>
+ <listitem>
+ <para><constant>:unsigned-long</constant> - Unsigned 32 or 64 bits, depending upon the platform.</para>
+ </listitem>
+ <listitem>
+ <para><constant>:float</constant> - 32-bit floating point.</para>
+ </listitem>
+ <listitem>
+ <para><constant>:double</constant> - 64-bit floating point.</para>
+ </listitem>
+ <listitem>
+ <para><constant>:cstring</constant> -
+ A &NULL; terminated string used for passing and returning characters strings with a &C; function.
+ </para>
+ </listitem>
+ <listitem>
+ <para><constant>:void</constant> -
+ The absence of a value. Used to indicate that a function does not return a value.
+ </para>
+ </listitem>
+ <listitem>
+ <para><constant>:pointer-void</constant> - Points to a generic object.</para>
+ </listitem>
+ <listitem>
+ <para><constant>*</constant> - Used to declare a pointer to an object</para>
+ </listitem>
+ </itemizedlist>
+ </partintro>
+
+ <refentry xml:id="uffi.def-constant">
+ <refnamediv>
+ <refname><function>def-constant</function></refname>
+ <refpurpose>Binds a symbol to a constant.
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>def-constant</funcdef>
+ <paramdef><parameter>name</parameter></paramdef>
+ <paramdef><parameter>value</parameter></paramdef>
+ <paramdef><parameter>&key;</parameter></paramdef>
+ <paramdef><parameter>export</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <para>A symbol that will be bound to the value.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>value</parameter></term>
+ <listitem>
+ <para>An evaluated form that is bound the the name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>export</parameter></term>
+ <listitem>
+ <para>When &t;, the name is exported from the current package. The default is &nil;</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>This is a thin wrapper around <function>defconstant</function>. It evaluates at
+ compile-time and optionally exports the symbol from the package.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+ (def-constant pi2 (* 2 pi))
+ (def-constant exported-pi2 (* 2 pi) :export t)</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>Creates a new special variable..</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.def-foreign-type">
+ <refnamediv>
+ <refname><function>def-foreign-type</function></refname>
+ <refpurpose>Defines a new foreign type.
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>def-foreign-type</funcdef>
+ <paramdef><parameter>name</parameter></paramdef>
+ <paramdef><parameter>type</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <para>A symbol naming the new foreign type.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>value</parameter></term>
+ <listitem>
+ <para>A form that is not evaluated that defines the new
+ foreign type.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>Defines a new foreign type.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+ (def-foreign-type my-generic-pointer :pointer-void)
+ (def-foreign-type a-double-float :double-float)
+ (def-foreign-type char-ptr (* :char))</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>Defines a new foreign type.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.null-char-p">
+ <refnamediv>
+ <refname><function>null-char-p</function></refname>
+ <refpurpose>Tests a character for &NULL; value.
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>null-char-p</funcdef>
+ <paramdef><parameter>char</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>char</parameter></term>
+ <listitem>
+ <para>A character or integer.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>returns</term>
+ <listitem>
+ <para>A boolean flag indicating if char is a &NULL; value.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>A predicate testing if a character or integer is &NULL;. This
+ abstracts the difference in implementations where some return a
+ <computeroutput>character</computeroutput> and some return a
+ <computeroutput>integer</computeroutput> whence dereferencing a
+ <computeroutput>C</computeroutput> character pointer.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <screen>
+(def-array-pointer ca :unsigned-char)
+ (let ((fs (convert-to-foreign-string "ab")))
+ (values (null-char-p (deref-array fs 'ca 0))
+ (null-char-p (deref-array fs 'ca 2))))
+=> &nil;
+ &t;</screen>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+ </reference>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 0
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY % eclent SYSTEM "../ecl.ent">
+%eclent;
+]>
+<book xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+ <reference xml:id="uffi.strings">
+ <title>Strings</title>
+ <partintro>
+ <title>Overview</title>
+ <para>
+ &UFFI; has functions to two types of <varname>C</varname>-compatible
+ strings: <emphasis>cstring</emphasis> and <emphasis>foreign</emphasis>
+ strings. cstrings are used <emphasis>only</emphasis> as parameters to
+ and from functions. In some implementations a cstring is not a foreign
+ type but rather the Lisp string itself. On other platforms a cstring
+ is a newly allocated foreign vector for storing characters. The
+ following is an example of using cstrings to both send and return a
+ value.
+ </para>
+
+ <programlisting>
+(uffi:def-function ("getenv" c-getenv)
+ ((name :cstring))
+ :returning :cstring)
+
+(defun my-getenv (key)
+ "Returns an environment variable, or NIL if it does not exist"
+ (check-type key string)
+ (uffi:with-cstring (key-native key)
+ (uffi:convert-from-cstring (c-getenv key-native))))
+ </programlisting>
+
+ <para>In contrast, foreign strings are always a foreign vector of characters
+ which have memory allocated. Thus, if you need to allocate memory to hold
+ the return value of a string, you must use a foreign string and not a
+ cstring. The following is an example of using a foreign string for a return
+ value.</para>
+
+ <programlisting>
+(uffi:def-function ("gethostname" c-gethostname)
+ ((name (* :unsigned-char))
+ (len :int))
+ :returning :int)
+
+(defun gethostname ()
+ "Returns the hostname"
+ (let* ((name (uffi:allocate-foreign-string 256))
+ (result-code (c-gethostname name 256))
+ (hostname (when (zerop result-code)
+ (uffi:convert-from-foreign-string name))))
+ ;; UFFI does not yet provide a universal way to free
+ ;; memory allocated by C's malloc. At this point, a program
+ ;; needs to call C's free function to free such memory.
+ (unless (zerop result-code)
+ (error "gethostname() failed."))))</programlisting>
+
+ <para>Foreign functions that return pointers to freshly allocated strings
+ should in general not return cstrings, but foreign strings. (There is no
+ portable way to release such cstrings from Lisp.) The following is an
+ example of handling such a function.</para>
+
+ <programlisting>
+(uffi:def-function ("readline" c-readline)
+ ((prompt :cstring))
+ :returning (* :char))
+
+(defun readline (prompt)
+ "Reads a string from console with line-editing."
+ (with-cstring (c-prompt prompt)
+ (let* ((c-str (c-readline c-prompt))
+ (str (convert-from-foreign-string c-str)))
+ (uffi:free-foreign-object c-str)
+ str)))
+ </programlisting>
+
+ </partintro>
+
+ <refentry xml:id="uffi.convert-from-cstring">
+ <refnamediv>
+ <refname><function>convert-from-cstring</function></refname>
+ <refpurpose>Converts a cstring to a Lisp string.</refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>convert-from-cstring</function>
+ <replaceable>cstring</replaceable>
+ =>
+ <returnvalue>string</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>cstring</parameter></term>
+ <listitem>
+ <para>A cstring.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>string</returnvalue></term>
+ <listitem>
+ <para>A Lisp string.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Converts a Lisp string to a <constant>cstring</constant>. This is
+ most often used when processing the results of a foreign function
+ that returns a cstring.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.convert-to-cstring">
+ <refnamediv>
+ <refname><function>convert-to-cstring</function></refname>
+ <refpurpose>Converts a Lisp string to a cstring.</refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>convert-to-cstring</function>
+ <replaceable>string</replaceable>
+ =>
+ <returnvalue>cstring</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem>
+ <para>A Lisp string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>cstring</returnvalue></term>
+ <listitem>
+ <para>A cstring.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Converts a Lisp string to a <varname>cstring</varname>. The
+ <varname>cstring</varname> should be freed with
+ <function>free-cstring</function>.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>On some implementations, this function allocates memory.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.free-cstring">
+ <refnamediv>
+ <refname><function>free-cstring</function></refname>
+ <refpurpose>Free memory used by cstring.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>free-cstring</function> <replaceable>cstring</replaceable>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>cstring</parameter></term>
+ <listitem>
+ <para>A cstring.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Frees any memory possibly allocated by
+ <function>convert-to-cstring</function>. On some implementions, a cstring is just the Lisp string itself.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.with-cstring">
+ <refnamediv>
+ <refname><function>with-cstring</function></refname>
+ <refpurpose>Binds a newly created cstring.</refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>with-cstring</function>
+ <replaceable>(cstring string) {body}</replaceable>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>cstring</parameter></term>
+ <listitem>
+ <para>A symbol naming the cstring to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem>
+ <para>A Lisp string that will be translated to a cstring.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>body</parameter></term>
+ <listitem>
+ <para>The body of where the cstring will be bound.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Binds a symbol to a cstring created from conversion of a
+ string. Automatically frees the <varname>cstring</varname>.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <para>
+ <programlisting>
+(def-function ("getenv" c-getenv)
+ ((name :cstring))
+ :returning :cstring)
+
+(defun getenv (key)
+ "Returns an environment variable, or NIL if it does not exist"
+ (check-type key string)
+ (with-cstring (key-cstring key)
+ (convert-from-cstring (c-getenv key-cstring))))</programlisting>
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.convert-from-foreign-string">
+ <refnamediv>
+ <refname><function>convert-from-foreign-string</function></refname>
+ <refpurpose>Converts a foreign string into a Lisp string.</refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>convert-from-foreign-string</function>
+ <replaceable>foreign-string &key length null-terminated-p</replaceable>
+ =>
+ <returnvalue>string</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>foreign-string</parameter></term>
+ <listitem>
+ <para>A foreign string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>length</parameter></term>
+ <listitem>
+ <para>The length of the foreign string to convert. The
+ default is the length of the string until a &NULL;
+ character is reached.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>null-terminated-p</parameter></term>
+ <listitem>
+ <para>A boolean flag with a default value of &t; When true,
+ the string is converted until the first &NULL; character is reached.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>string</returnvalue></term>
+ <listitem>
+ <para>A Lisp string.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Returns a Lisp string from a foreign string.
+ Can translated ASCII and binary strings.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+
+ <refentry xml:id="uffi.convert-to-foreign-string">
+ <refnamediv>
+ <refname><function>convert-to-foreign-string</function></refname>
+ <refpurpose>Converts a Lisp string to a foreign string.
+ </refpurpose>
+ <refclass>Macro</refclass>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Syntax</title>
+ <synopsis>
+ <function>convert-to-foreign-string</function>
+ <replaceable>string</replaceable> =>
+ <returnvalue>foreign-string</returnvalue>
+ </synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments and Values</title>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem>
+ <para>A Lisp string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>foreign-string</returnvalue></term>
+ <listitem>
+ <para>A foreign string.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Converts a Lisp string to a foreign string. Memory should be
+ freed with <function>free-foreign-object</function>.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ <refentry xml:id="uffi.allocate-foreign-string">
+ <refnamediv>
+ <refname><function>allocate-foreign-string</function></refname>
+ <refpurpose>Allocates space for a foreign string.
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <title>Macro</title>
+ <synopsis>
+ <function>allocate-foreign-string</function> <replaceable>size
+ &key unsigned</replaceable> =>
+ <returnvalue>foreign-string</returnvalue>
+ </synopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>size</parameter></term>
+ <listitem>
+ <para>The size of the space to be allocated in bytes.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>unsigned</parameter></term>
+ <listitem>
+ <para>A boolean flag with a default value of &t;. When true,
+ marks the pointer as an <constant>:unsigned-char</constant>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>foreign-string</returnvalue></term>
+ <listitem>
+ <para>A foreign string which has undefined contents.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Allocates space for a foreign string. Memory should
+ be freed with <function>free-foreign-object</function>.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Side Effects</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Affected by</title>
+ <para>None.</para>
+ </refsect1>
+ <refsect1>
+ <title>Exceptional Situations</title>
+ <para>None.</para>
+ </refsect1>
+ </refentry>
+
+ </reference>
+</book>
+<!-- Keep this comment at the end of the file
+ Local variables:
+ mode: nxml
+ sgml-indent-step: 1
+ nxml-child-indent: 1
+ nxml-outline-child-indent: 0
+ fill-column: 79
+ End:
+-->
--- /dev/null
+<?xml version="1.0"?>
+<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
+ <uri resource="ref_aggregate.xml" typeId="DocBook5"/>
+ <uri resource="ref_declare.xml" typeId="DocBook5"/>
+ <uri resource="ref_func_libr.xml" typeId="DocBook5"/>
+ <uri resource="ref_object.xml" typeId="DocBook5"/>
+ <uri resource="ref_primitive.xml" typeId="DocBook5"/>
+ <uri resource="ref_string.xml" typeId="DocBook5"/>
+ <typeId id="DocBook5" uri="/usr/local/Cellar/docbook/5.0/docbook/xml/5.0/rng/docbookxi.rnc"/>
+ <namespace ns="http://docbook.org/ns/docbook" uri="/usr/local/Cellar/docbook/5.0/docbook/xml/5.0/rng/docbookxi.rnc"/>
+</locatingRules>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:a="http://docbook.org/ns/docbook"
+ exclude-result-prefixes="a"
+ version="1.0">
+<xsl:output encoding="utf-8"/>
+
+<!-- By default copy the whole document -->
+<xsl:template match="node()|@*">
+ <xsl:copy>
+ <xsl:apply-templates select="node()|@*"/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="a:refsynopsisdiv">
+ <xsl:for-each select=".//a:symbol">
+ <xsl:element name="indexterm">
+ <xsl:attribute name="type">cl</xsl:attribute>
+ <primary><xsl:value-of select="."/></primary>
+ </xsl:element>
+ </xsl:for-each>
+ <xsl:for-each select=".//a:funcsynopsis//a:function|
+ .//a:synopsys//a:type|
+ .//a:synopsys//a:variable|
+ .//a:synopsys//a:constant">
+ <xsl:if test="string-length(attribute::role)=0">
+ <xsl:element name="indexterm">
+ <xsl:attribute name="type">c</xsl:attribute>
+ <primary><xsl:value-of select="."/></primary>
+ </xsl:element>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:copy-of select="."/>
+</xsl:template>
+
+<!--
+<xsl:template match="a:symbol" mode="automatic">
+ <xsl:copy-of select="."/>
+ <indexterm type="cl">
+ <primary><xsl:value-of select="."/></primary>
+ </indexterm>
+</xsl:template>
+
+<xsl:template match="a:function" mode="automatic">
+ <xsl:copy-of select="."/>
+ <indexterm type="c">
+ <primary><xsl:value-of select="."/></primary>
+ </indexterm>
+</xsl:template>
+
+<xsl:template match="a:variable" mode="automatic">
+ <xsl:copy-of select="."/>
+ <indexterm type="c">
+ <primary><xsl:value-of select="."/></primary>
+ </indexterm>
+</xsl:template>
+
+<xsl:template match="a:type" mode="automatic">
+ <xsl:copy-of select="."/>
+ <indexterm type="c">
+ <primary><xsl:value-of select="."/></primary>
+ </indexterm>
+</xsl:template>
+-->
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'>
+<xsl:param name="html.stylesheet">ecl.css</xsl:param>
+<xsl:param name="funcsynopsis.style">common-lisp</xsl:param>
+<xsl:param name="toc.title.p" select="0"/>
+<xsl:param name="toc.section.depth" select="3"/>
+<xsl:param name="generate.section.toc.level" select="2"/>
+<xsl:param name="section.autolabel" select="1"/>
+<xsl:param name="section.label.includes.component.label" select="1"></xsl:param>
+<xsl:param name="label.from.part" select="1"></xsl:param>
+<xsl:param name="bridgehead.in.toc" select="1"></xsl:param>
+<xsl:param name="xref.with.number.and.title" select="0"/>
+<xsl:param name="refentry.generate.name" select="1"/>
+<xsl:param name="refentry.generate.title" select="0"/>
+<xsl:param name="variablelist.as.table" select="1"/>
+<xsl:param name="chunk.separate.lots" select="1"/>
+<xsl:param name="generate.index" select="1"/>
+<xsl:param name="index.on.type" select="1"/>
+<xsl:param condition="html" name="generate.toc">
+appendix toc
+article/appendix nop
+article toc
+book toc,figure,table,example,equation
+chapter toc
+part toc
+preface toc
+reference toc
+sect1 nop
+sect2 nop
+sect3 nop
+sect4 nop
+sect5 nop
+section nop
+set toc
+</xsl:param>
+</xsl:stylesheet>
+
--- /dev/null
+<?xml version='1.0'?>
+<!DOCTYPE xsl:stylesheet [
+<!ENTITY RE " ">
+<!ENTITY nbsp " ">
+]>
+<xsl:stylesheet exclude-result-prefixes="d"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:d="http://docbook.org/ns/docbook"
+xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ version='1.0'>
+
+<xsl:template match="d:funcprototype">
+
+ <xsl:variable name="style">
+ <xsl:call-template name="funcsynopsis.style"/>
+ </xsl:variable>
+
+ <fo:block font-family="{$monospace.font.family}"
+ space-before.minimum="0.8em"
+ space-before.optimum="1em"
+ space-before.maximum="1.2em">
+ <xsl:choose>
+ <xsl:when test="$style='kr'">
+ <xsl:apply-templates/>
+ <fo:block
+ space-before.minimum="0.8em"
+ space-before.optimum="1em"
+ space-before.maximum="1.2em">
+ <xsl:apply-templates select="./d:paramdef" mode="kr-funcsynopsis-mode"/>
+ </fo:block>
+ </xsl:when>
+ <xsl:when test="$style='common-lisp'">
+ <fo:block
+ space-before.minimum="0.8em"
+ space-before.optimum="1em"
+ space-before.maximum="1.2em">
+ (<xsl:apply-templates select="./d:funcdef" mode="cl-funcsynopsis-mode"/>
+ <xsl:apply-templates select="./d:paramdef" mode="cl-funcsynopsis-mode"/>)
+ </fo:block>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </fo:block>
+</xsl:template>
+
+<xsl:template match="d:funcdef" mode="kr-funcsynopsis-mode">
+ <fo:inline font-family="{$monospace.font.family}">
+ <xsl:apply-templates/>
+ </fo:inline>
+</xsl:template>
+
+<xsl:template match="d:paramdef" mode="kr-funcsynopsis-mode">
+ <fo:block>
+ <xsl:apply-templates/>
+ <xsl:text> </xsl:text>
+ </fo:block>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version='1.0'?>
+<!DOCTYPE xsl:stylesheet [
+<!ENTITY nbsp " ">
+]>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'>
+
+<!-- ====================================================================== -->
+<!-- funcprototype -->
+<!--
+
+funcprototype ::= (funcdef,
+ (void|varargs|paramdef+))
+
+funcdef ::= (#PCDATA|type|replaceable|function)*
+
+paramdef ::= (#PCDATA|type|replaceable|parameter|funcparams)*
+-->
+
+<xsl:template match="funcprototype">
+ <xsl:variable name="html-style">
+ <xsl:call-template name="dbhtml-attribute">
+ <xsl:with-param name="pis"
+ select="ancestor::funcsynopsis//processing-instruction('dbhtml')"/>
+ <xsl:with-param name="attribute" select="'funcsynopsis-style'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="style">
+ <xsl:choose>
+ <xsl:when test="$html-style != ''">
+ <xsl:value-of select="$html-style"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$funcsynopsis.style"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="$style = 'kr'">
+ <xsl:apply-templates select="." mode="kr-nontabular"/>
+ </xsl:when>
+ <xsl:when test="$style = 'common-lisp'">
+ <xsl:apply-templates select="." mode="common-lisp"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="." mode="ansi-nontabular"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!-- ====================================================================== -->
+<!-- funcprototype: common-lisp -->
+
+<xsl:template match="funcprototype" mode="common-lisp">
+ <p>
+ <xsl:apply-templates mode="common-lisp"/>
+ </p>
+</xsl:template>
+
+<xsl:template match="funcdef" mode="common-lisp">
+ <code class="{name(.)}">
+ <xsl:text>(</xsl:text>
+ <xsl:apply-templates mode="common-lisp"/>
+ </code>
+</xsl:template>
+
+<xsl:template match="funcdef/function" mode="common-lisp">
+ <xsl:choose>
+ <xsl:when test="$funcsynopsis.decoration != 0">
+ <b class="fsfunc"><xsl:apply-templates mode="common-lisp"/></b>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates mode="common-lisp"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="void" mode="common-lisp">
+ <code>)</code>
+</xsl:template>
+
+<xsl:template match="varargs" mode="common-lisp">
+</xsl:template>
+
+<xsl:template match="paramdef" mode="common-lisp">
+ <xsl:text> </xsl:text><xsl:apply-templates mode="common-lisp"/>
+ <xsl:choose>
+ <xsl:when test="following-sibling::*">
+ <xsl:text> </xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>)</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="paramdef/parameter" mode="common-lisp">
+ <xsl:choose>
+ <xsl:when test="$funcsynopsis.decoration != 0">
+ <var class="pdparam">
+ <xsl:apply-templates mode="common-lisp"/>
+ </var>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates mode="common-lisp"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="funcparams" mode="common-lisp">
+ <xsl:apply-templates mode="common-lisp"/>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'>
+<!-- In Docbook, a Section does not add its RefEntry to the TOC. -->
+
+<xsl:template match="section" mode="toc">
+ <xsl:param name="toc-context" select="."/>
+
+ <xsl:call-template name="subtoc">
+ <xsl:with-param name="toc-context" select="$toc-context"/>
+ <xsl:with-param name="nodes" select="section|refentry
+ |bridgehead[$bridgehead.in.toc != 0]"/>
+ </xsl:call-template>
+</xsl:template>
+
+</xsl:stylesheet>
+