doc: cosmetic improvements

Consistent formatting and capitalization, clickable links to functions
defined in other parts of the manual, better looking css for html
output. Some small errors and typos have been corrected as well.
This commit is contained in:
Marius Gerbershagen 2020-02-03 18:58:29 +01:00
parent b85d628955
commit c530793d2b
47 changed files with 1726 additions and 1667 deletions

View file

@ -16,7 +16,7 @@ ecl.info.gz: $(FILES)
gzip < ecl.info > ecl.info.gz
html/index.html: $(FILES)
$(MAKEINFO) --html --css-include=ecl.css --split=chapter manual.txi
$(MAKEINFO) --html --css-include=ecl.css --split=section manual.txi
rm -rf html
mv ecl html
cp -r figures html

View file

@ -6,9 +6,9 @@ system. Call to @code{eval} invokes the bytecode compiler and then the
bytecode interpreter.
@itemize
@item @code{src/c/compiler.d} - bytecode compiler
@item @code{src/c/interpreter.d} - bytecode interpreter
@item @code{src/c/interpreter.d} - bytecode disassembler
@item @file{src/c/compiler.d} - bytecode compiler
@item @file{src/c/interpreter.d} - bytecode interpreter
@item @file{src/c/disassembler.d} - bytecode disassembler
@end itemize
Structure @code{ecl_bytecodes} has the following fields:
@ -30,7 +30,7 @@ Moreover if bytecompiled function is a closure then its structure is
@itemize
@item @code{code} - closure function (@code{ecl_bytecodes})
@item @code{lex} - closure lexical environment
@item @code{entry} - closure entry address (function _ecl_bclosure_dispatch_vararg)
@item @code{entry} - closure entry address (function @code{_ecl_bclosure_dispatch_vararg})
@end itemize
@subsection Bytecode compiler
@ -39,6 +39,6 @@ Moreover if bytecompiled function is a closure then its structure is
@subsection Bytecode disassembler
@defun{si:bc-split} {@var{function}}
@defun si:bc-split function
Returns five values: lex, bytecodes, data and name.
@end defun

View file

@ -100,9 +100,9 @@ The C function @code{L1add1} implements the Lisp function @code{add1}. This rela
@subsection Implementation of Compiled Closures
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.
Ordinarily, lexical variables in a compiled function @var{f} 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 @var{f}. 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.
Ordinarily, lexical variables in a compiled function @code{f} 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 @code{f}. 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.
The environment list is a pushdown list: It is empty when @var{f} 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 @var{f}, 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 @var{f}, the compiled code for the closure is coupled with the environment list at that moment to form the compiled closure.
The environment list is a pushdown list: It is empty when @code{f} 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 @code{f}, 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 @code{f}, the compiled code for the closure is coupled with the environment list at that moment to form the compiled closure.
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.
@ -164,7 +164,7 @@ Declarations, especially type and function declarations, increase the efficiency
@end lisp
The compiler generates the following C code (Note that the tail-recursive call of @code{TAK} was replaced by iteration):
The compiler generates the following C code (Note that the tail-recursive call of @code{tak} was replaced by iteration):
@example
@verbatim
/* function definition for TAK */

View file

@ -65,9 +65,9 @@ Function return:
@end verbatim
@end example
Return function expands into a lexical block @verb{|{}|}, so if it's
used inside IF/ELSE, then it should be enclosed, even if we
use sole @verb{|@(return);|}, because ";" will be treated as the next
Return function expands into a lexical block @code{@{@}}, so if it's
used inside @code{if/else}, then it should be enclosed, even if we
use sole @code{@@(return);}, because ";" will be treated as the next
instruction.
Symbols:
@ -79,7 +79,7 @@ Symbols:
@end example
Expands into a C statement, whole value is the given symbol
from symbols_list.h
from @file{symbols_list.h}
@example
@verbatim
@ -87,6 +87,6 @@ from symbols_list.h
@end verbatim
@end example
Expands into a C statement, whole value is a fixnum
corresponding to the index in the builtin symbols table of the
given symbol from symbols_list.h. Used for handling type errors.
Expands into a C statement, whole value is a fixnum corresponding to the
index in the builtin symbols table of the given symbol from
@file{symbols_list.h}. Used for handling type errors.

View file

@ -83,7 +83,7 @@ need to know about all these conventions. There is a preprocessor
(@pxref{Defun 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
@code{cl_last} in @code{src/c/list.d} is
@code{cl_last} in @file{src/c/list.d} is
@example
@verbatim
@ -107,7 +107,7 @@ Note that this list is different from what the Common Lisp standard
calls a lexical environment, which is the content of a
@code{&environment} parameter to @code{defmacro}. For the differences
between this two environments see the comments in
@code{src/c/compiler.d} and @code{src/c/interpreter.d}.
@file{src/c/compiler.d} and @file{src/c/interpreter.d}.
@node The interpreter stack
@subsection The interpreter stack
@ -115,7 +115,7 @@ between this two environments see the comments in
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 @code{FORMAT}, etc.
saving compiled code, keeping arguments to @code{format}, etc.
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
@ -130,7 +130,7 @@ lisp objects on the stack:
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 @code{NIL}. In the first case,
cases the lexical environment is just @code{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.

View file

@ -9,7 +9,7 @@
If you want to extend, fix or simply customize ECL for your own needs,
you should understand how the implementation works.
@cppindex cl_lispunion
@cppdef cl_lispunion
@deftp @cind{} cl_lispunion { cons big ratio SF DF longfloat gencomplex csfloat cdfloat clfloat symbol pack hash array vector base_string string stream random readtable pathname bytecodes bclosure cfun cfunfixed cclosure d instance process queue lock rwlock condition_variable semaphore barrier mailbox cblock foreign frame weak sse }
Union containing all first-class ECL types.
@ -92,7 +92,7 @@ comments in the source code):
*/
@end verbatim
@cppindex cl_object
@cppdef cl_object
@deftp @cind{} cl_object
This is the type of a lisp object. For your C/C++ program, a cl_object
can be either a fixnum, a character, or a pointer to a union of
@ -131,63 +131,63 @@ how to use the different fields of a @code{cl_object} pointer.
Enumeration type which distinguishes the different types of lisp
objects. The most important values are:
@cppindex t_start
@cppindex t_list
@cppindex t_character
@cppindex t_fixnum
@cppindex t_bignum
@cppindex t_ratio
@c @cppindex t_shortfloat
@cppindex t_singlefloat
@cppdef t_start
@cppdef t_list
@cppdef t_character
@cppdef t_fixnum
@cppdef t_bignum
@cppdef t_ratio
@c @cppdef t_shortfloat
@cppdef t_singlefloat
@c #ifdef ECL_LONG_FLOAT
@cppindex t_longfloat
@cppdef t_longfloat
@c #endif
@cppindex t_complex
@cppdef t_complex
@c #ifdef ECL_COMPLEX_FLOAT
@cppindex t_csfloat
@cppindex t_cdfloat
@cppindex t_clfloat
@cppdef t_csfloat
@cppdef t_cdfloat
@cppdef t_clfloat
@c #endif
@cppindex t_symbol
@cppindex t_package
@cppindex t_hashtable
@cppindex t_array
@cppindex t_vector
@cppdef t_symbol
@cppdef t_package
@cppdef t_hashtable
@cppdef t_array
@cppdef t_vector
@c #ifdef ECL_UNICODE
@cppindex t_string
@cppdef t_string
@c #endif
@cppindex t_base_string
@cppindex t_bitvector
@cppindex t_stream
@cppindex t_random
@cppindex t_readtable
@cppindex t_pathname
@cppindex t_bytecodes
@cppindex t_bclosure
@cppindex t_cfun
@cppindex t_cfunfixed
@cppindex t_cclosure
@cppindex t_instance
@cppindex t_structure = t_instance
@cppdef t_base_string
@cppdef t_bitvector
@cppdef t_stream
@cppdef t_random
@cppdef t_readtable
@cppdef t_pathname
@cppdef t_bytecodes
@cppdef t_bclosure
@cppdef t_cfun
@cppdef t_cfunfixed
@cppdef t_cclosure
@cppdef t_instance
@cppdef t_structure = t_instance
@c #ifdef ECL_THREADS
@cppindex t_process
@cppindex t_lock
@cppindex t_rwlock
@cppindex t_condition_variable
@cppindex t_semaphore
@cppindex t_barrier
@cppindex t_mailbox
@cppdef t_process
@cppdef t_lock
@cppdef t_rwlock
@cppdef t_condition_variable
@cppdef t_semaphore
@cppdef t_barrier
@cppdef t_mailbox
@c #endif
@cppindex t_codeblock
@cppindex t_foreign
@cppindex t_frame
@cppindex t_weak_pointer
@cppdef t_codeblock
@cppdef t_foreign
@cppdef t_frame
@cppdef t_weak_pointer
@c #ifdef ECL_SSE2
@cppindex t_sse_pack
@cppdef t_sse_pack
@c #endif
@cppindex t_end
@cppindex t_other
@cppindex t_contiguous contiguous block
@cppdef t_end
@cppdef t_other
@cppdef t_contiguous contiguous block
@code{t_cons} @code{t_fixnum}, @code{t_character}, @code{t_bignum},
@code{t_ratio}, @code{t_singlefloat}, @code{t_doublefloat},
@ -198,39 +198,39 @@ objects. The most important values are:
@code{t_instance}, @code{t_foreign} and @code{t_thread}.
@end deftp
@cppindex ecl_t_of
@cppdef ecl_t_of
@deftypefun cl_type ecl_t_of (cl_object x)
If @var{x} is a valid lisp object, @code{ecl_t_of(x)} returns an integer
denoting the type that lisp object. That integer is one of the values of
the enumeration type @code{cl_type}.
@end deftypefun
@cppindex ECL_CHARACTERP
@cppindex ECL_BASE_CHAR_P
@cppindex ECL_BASE_CHAR_CODE_P
@cppindex ECL_NUMBER_TYPE_P
@cppindex ECL_COMPLEXP
@cppindex ECL_REAL_TYPE_P
@cppindex ECL_FIXNUMP
@cppindex ECL_BIGNUMP
@cppindex ECL_SINGLE_FLOAT_P
@cppindex ECL_DOUBLE_FLOAT_P
@cppindex ECL_LONG_FLOAT_P
@cppindex ECL_CONSP
@cppindex ECL_LISTP
@cppindex ECL_ATOM
@cppindex ECL_SYMBOLP
@cppindex ECL_ARRAYP
@cppindex ECL_VECTORP
@cppindex ECL_BIT_VECTOR_P
@cppindex ECL_STRINGP
@cppindex ECL_HASH_TABLE_P
@cppindex ECL_RANDOM_STATE_P
@cppindex ECL_PACKAGEP
@cppindex ECL_PATHNAMEP
@cppindex ECL_READTABLEP
@cppindex ECL_FOREIGN_DATA_P
@cppindex ECL_SSE_PACK_P
@cppdef ECL_CHARACTERP
@cppdef ECL_BASE_CHAR_P
@cppdef ECL_BASE_CHAR_CODE_P
@cppdef ECL_NUMBER_TYPE_P
@cppdef ECL_COMPLEXP
@cppdef ECL_REAL_TYPE_P
@cppdef ECL_FIXNUMP
@cppdef ECL_BIGNUMP
@cppdef ECL_SINGLE_FLOAT_P
@cppdef ECL_DOUBLE_FLOAT_P
@cppdef ECL_LONG_FLOAT_P
@cppdef ECL_CONSP
@cppdef ECL_LISTP
@cppdef ECL_ATOM
@cppdef ECL_SYMBOLP
@cppdef ECL_ARRAYP
@cppdef ECL_VECTORP
@cppdef ECL_BIT_VECTOR_P
@cppdef ECL_STRINGP
@cppdef ECL_HASH_TABLE_P
@cppdef ECL_RANDOM_STATE_P
@cppdef ECL_PACKAGEP
@cppdef ECL_PATHNAMEP
@cppdef ECL_READTABLEP
@cppdef ECL_FOREIGN_DATA_P
@cppdef ECL_SSE_PACK_P
@deftypefun bool ECL_CHARACTERP (cl_object o)
@deftypefunx bool ECL_BASE_CHAR_P (cl_object o)
@ -264,7 +264,7 @@ type. These checks have been optimized, and are preferred over several
calls to @code{ecl_t_of}.
@end deftypefun
@cppindex ECL_IMMEDIATE
@cppdef ECL_IMMEDIATE
@deftypefun bool ECL_IMMEDIATE (cl_object o)
Tells whether @var{x} is an immediate datatype.
@end deftypefun
@ -285,24 +285,24 @@ the functionality in the lisp environment. In those cases you need to
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.
@cppindex c_string_to_object
@cppindex ecl_read_from_cstring
@cppindex si_string_to_object
@cppdef c_string_to_object
@cppdef ecl_read_from_cstring
@cppdef si_string_to_object
@defun si::string-to-object string &optional (err-value nil)
@end defun
@deftypefun cl_object si_string_to_object (cl_narg narg, cl_object str, ...)
@deftypefunx cl_object ecl_read_from_cstring (const char *s)
@code{ecl_read_from_cstring} builds a lisp object from a C string
@coderef{ecl_read_from_cstring} builds a lisp object from a C string
which contains a suitable representation of a lisp
object. @code{si_string_to_object} performs the same task, but uses a
object. @coderef{si_string_to_object} performs the same task, but uses a
lisp string, and therefore it is less useful.
@itemize @bullet
@item @strong{DEPRECATED} @code{c_string_to_object} equivalent to @code{ecl_read_from_cstring}
@item @strong{DEPRECATED} @coderef{c_string_to_object} equivalent to @coderef{ecl_read_from_cstring}
@end itemize
@subsubheading Example
@exindex @code{ecl_read_from_cstring} constructing Lisp objects in C
@exindex @coderef{ecl_read_from_cstring} constructing Lisp objects in C
Using a C string
@example
@ -320,7 +320,7 @@ cl_object array2 = si_string_to_object(string);
Common-Lisp distinguishes two types of integer types: @code{bignum}s and
@code{fixnum}s. A fixnum is a small integer, which ideally occupies only
a word of memory and which is between the values
@code{MOST-NEGATIVE-FIXNUM} and @code{MOST-POSITIVE-FIXNUM}. A
@coderef{MOST-NEGATIVE-FIXNUM} and @coderef{MOST-POSITIVE-FIXNUM}. A
@code{bignum} is any integer which is not a @code{fixnum} and it is only
constrained by the amount of memory available to represent it.
@ -333,7 +333,7 @@ your C extensions are portable. All other integers are stored as
amount of memory and the GNU Multiprecision Library is required to
create, manipulate and calculate with them.
@cppindex cl_fixnum
@cppdef cl_fixnum
@deftp @cind{} cl_fixnum
This is a C signed integer type capable of holding a whole @code{fixnum}
without any loss of precision. The opposite is not true, and you may
@ -341,28 +341,28 @@ create a @code{cl_fixnum} which exceeds the limits of a fixnum and
should be stored as a @code{bignum}.
@end deftp
@cppindex cl_index
@cppdef cl_index
@deftp @cind{} cl_index
This is a C unsigned integer type capable of holding a non-negative
@code{fixnum} without loss of precision. Typically, a @code{cl_index} is
used as an index into an array, or into a proper list, etc.
@end deftp
@cppindex MOST_NEGATIVE_FIXNUM
@cppindex MOST_POSITIVE_FIXNUM
@lspindex MOST-NEGATIVE-FIXNUM
@lspindex MOST-POSITIVE-FIXNUM
@cppdef MOST_NEGATIVE_FIXNUM
@cppdef MOST_POSITIVE_FIXNUM
@lspdef MOST-NEGATIVE-FIXNUM
@lspdef MOST-POSITIVE-FIXNUM
@defvr {Constant} MOST_NEGATIVE_FIXNUM
@defvrx {Constant} MOST_POSITIVE_FIXNUM
These constants mark the limits of a @code{fixnum}.
@end defvr
@cppindex ecl_fixnum_lower
@cppindex ecl_fixnum_greater
@cppindex ecl_fixnum_leq
@cppindex ecl_fixnum_geq
@cppindex ecl_fixnum_plusp
@cppindex ecl_fixnum_minusp
@cppdef ecl_fixnum_lower
@cppdef ecl_fixnum_greater
@cppdef ecl_fixnum_leq
@cppdef ecl_fixnum_geq
@cppdef ecl_fixnum_plusp
@cppdef ecl_fixnum_minusp
@deftypefun bool ecl_fixnum_lower (cl_fixnum a, cl_fixnum b)
@deftypefunx bool ecl_fixnum_greater (cl_fixnum a, cl_fixnum b)
@deftypefunx bool ecl_fixnum_leq (cl_fixnum a, cl_fixnum b)
@ -389,12 +389,14 @@ integer). These functions do @strong{not} check their arguments.
@cppindex cl_fixnum
@cppindex cl_index
@cppdef fixint
@cppdef fixnint
@deftypefun cl_fixnum fixint (cl_object o)
@deftypefunx cl_index fixnint (cl_object o)
Safe conversion of a lisp @code{fixnum} to a C integer of the
appropriate size. Signals an error if @var{o} is not of fixnum type.
@code{fixnint} additionally ensure that @var{o} is not negative.
@coderef{fixnint} additionally ensure that @var{o} is not negative.
@end deftypefun
@subheading Characters
@ -411,9 +413,9 @@ the other is used when ECL is built with a configure option
@deftp @cind{} ecl_character
Immediate type @code{t_character}. If ECL built with Unicode support,
then may be either base or extended character, which may be
distinguished with the predicate @code{ECL_BASE_CHAR_P}.
distinguished with the predicate @coderef{ECL_BASE_CHAR_P}.
Additionally we have @code{ecl_base_char} for base strings, which is an
Additionally we have @coderef{ecl_base_char} for base strings, which is an
equivalent to the ordinary char.
@subsubheading Example
@ -444,11 +446,11 @@ Each character is assigned an integer code which ranges from 0 to
@deftypefunx ecl_character ECL_CHAR_CODE (cl_object o)
@deftypefunx ecl_character ecl_char_code (cl_object o)
@deftypefunx ecl_base_char ecl_base_char_code (cl_object o)
@code{ECL_CHAR_CODE}, @code{ecl_char_code} and @code{ecl_base_char_code}
return the integer code associated to a lisp
character. @code{ecl_char_code} and @code{ecl_base_char_code} perform a
safe conversion, while @code{ECL_CHAR_CODE} doesn't check its
argument.
@code{ECL_CHAR_CODE}, @code{ecl_char_code} and
@code{ecl_base_char_code} return the integer code associated to a
lisp character. @code{ecl_char_code} and @code{ecl_base_char_code}
perform a safe conversion, while @code{ECL_CHAR_CODE} doesn't check
its argument.
@code{ECL_CODE_CHAR} returns the lisp character associated to an integer
code. It does not check its arguments.
@ -459,21 +461,21 @@ code. It does not check its arguments.
@end itemize
@end deftypefun
@cppindex ecl_char_eq
@cppindex ecl_char_equal
@cppdef ecl_char_eq
@cppdef ecl_char_equal
@deftypefun bool ecl_char_eq (cl_object x, cl_object y)
@deftypefunx bool ecl_char_equal (cl_object x, cl_object y)
Compare two characters for equality. char_eq take case into account and
char_equal ignores it.
@end deftypefun
@cppindex ecl_char_cmp
@cppindex ecl_char_compare
@cppdef ecl_char_cmp
@cppdef ecl_char_compare
@deftypefun int ecl_char_cmp (cl_object x, cl_object y)
@deftypefunx int ecl_char_compare (cl_object x, cl_object y)
Compare the relative order of two characters. @code{char_cmp} takes care
of case and @code{char_compare} converts all characters to uppercase
before comparing them.
Compare the relative order of two characters. @coderef{ecl_char_cmp}
takes care of case and @coderef{ecl_char_compare} converts all
characters to uppercase before comparing them.
@end deftypefun
@subheading Arrays
@ -484,8 +486,8 @@ 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 bit-vector, a multidimensional array or a string.
@cppindex ECL_ADJUSTABLE_ARRAY_P
@cppindex ECL_ARRAY_HAS_FILL_POINTER_P
@cppdef ECL_ADJUSTABLE_ARRAY_P
@cppdef ECL_ARRAY_HAS_FILL_POINTER_P
@deftypefun bool ECL_ADJUSTABLE_ARRAY_P (cl_object x)
@deftypefunx bool ECL_ARRAY_HAS_FILL_POINTER_P (cl_object x)
All arrays (arrays, strings and bit-vectors) may be tested for being
@ -493,7 +495,7 @@ adjustable and whenever they have a fill pointer with this two
macros. They don't check the type of their arguments.
@end deftypefun
@cppindex ecl_vector
@cppdef ecl_vector
@deftp @cind{} ecl_vector
If @code{x} contains a vector, you can access the following fields:
@ -501,8 +503,8 @@ If @code{x} contains a vector, you can access the following fields:
@item x->vector.elttype
The type of the elements of the vector.
@item x->vector.displaced
List storing the vectors that x is displaced from and that x displaces
to.
List storing the vectors that @code{x} is displaced from and that x
displaces to.
@item x->vector.dim
The maximum number of elements.
@item x->vector.fillp
@ -513,7 +515,7 @@ pointer depending on @var{x->vector.elttype}.
@end table
@end deftp
@cppindex ecl_array
@cppdef ecl_array
@deftp @cind{} ecl_array
If @code{x} contains a multidimensional array, you can access the
following fields:
@ -524,8 +526,8 @@ The type of the elements of the array.
@item x->array.rank
The number of array dimensions.
@item x->array.displaced
List storing the arrays that x is displaced from and that x displaces
to.
List storing the arrays that @code{x} is displaced from and that x
displaces to.
@item x->array.dim
The maximum number of elements.
@item x->array.dims[]
@ -549,13 +551,13 @@ value of @code{x->array.elttype} or @code{x->vector.elttype}. We list
some of those types together with the C constant that denotes that type:
@table @var
@item T
@item t
@code{ecl_aet_object}
@item SINGLE-FLOAT
@item single-float
@code{ecl_aet_sf}
@item DOUBLE-FLOAT
@item double-float
@code{ecl_aet_df}
@item LONG-FLOAT
@item long-float
@code{ecl_aet_lf}
@item (COMPLEX SINGLE-FLOAT)
@code{ecl_aet_csf}
@ -639,8 +641,8 @@ zero terminated C string. Thus, if a string has n characters, ECL will
reserve n+1 bytes for the base-string. This allows us to pass the
base-string self pointer to any C routine.
@cppindex ecl_string
@cppindex ecl_base_string
@cppdef ecl_string
@cppdef ecl_base_string
@deftp @cind{} ecl_string
@deftpx @cind{} ecl_base_string
If @code{x} is a lisp object of type string or a base-string, we can
@ -655,8 +657,8 @@ Pointer to the characters (appropriately @code{ecl_character}'s and @code{ecl_ba
@end table
@end deftp
@cppindex ECL_EXTENDED_STRING_P
@cppindex ECL_BASE_STRING_P
@cppdef ECL_EXTENDED_STRING_P
@cppdef ECL_BASE_STRING_P
@deftypefun bool ECL_EXTENDED_STRING_P (cl_object object)
@deftypefunx bool ECL_BASE_STRING_P (cl_object object)
@ -684,11 +686,11 @@ separate package @var{GRAY}. We may redefine functions in the
@var{COMMON-LISP} package with a function @code{redefine-cl-functions}
at run-time.
@cppindex ecl_file_pos
@cppdef ecl_file_pos
@deftp @cind{} ecl_file_ops write_* read_* unread_* peek_* listen clear_input clear_output finish_output force_output input_p output_p interactive_p element_type length get_position set_position column close
@end deftp
@cppindex ecl_stream
@cppdef ecl_stream
@deftp @cind{} ecl_stream
@table @code
@item ecl_smmode mode
@ -730,12 +732,12 @@ Character table, flags, etc
@end table
@end deftp
@cppindex ECL_ANSI_STREAM_P
@cppdef ECL_ANSI_STREAM_P
@deftypefun bool ECL_ANSI_STREAM_P (cl_object o)
Predicate determining if @code{o} is a first-class stream object.
@end deftypefun
@cppindex ECL_ANSI_STREAM_TYPE_P
@cppdef ECL_ANSI_STREAM_TYPE_P
@deftypefun bool ECL_ANSI_STREAM_TYPE_P (cl_object o, ecl_smmode m)
Predicate determining if @code{o} is a first-class stream object of
type @code{m}.
@ -747,11 +749,11 @@ Structures and instances share the same datatype @code{t_instance} (
with a few exceptions. Structure implementation details are the file
@code{src/c/structure.d}.
@cppindex ECL_STRUCT_TYPE
@cppindex ECL_STRUCT_SLOTS
@cppindex ECL_STRUCT_LENGTH
@cppindex ECL_STRUCT_SLOT
@cppindex ECL_STRUCT_NAME
@cppdef ECL_STRUCT_TYPE
@cppdef ECL_STRUCT_SLOTS
@cppdef ECL_STRUCT_LENGTH
@cppdef ECL_STRUCT_SLOT
@cppdef ECL_STRUCT_NAME
@deftypefun cl_object ECL_STRUCT_TYPE (cl_object x)
@deftypefunx cl_object ECL_STRUCT_SLOTS (cl_object x)
@deftypefunx cl_object ECL_STRUCT_LENGTH (cl_object x)
@ -762,15 +764,15 @@ Convenience functions for the structures.
@subheading Instances
@cppindex ECL_CLASS_OF
@cppindex ECL_SPEC_FLAG
@cppindex ECL_SPEC_OBJECT
@cppindex ECL_CLASS_NAME
@cppindex ECL_CLASS_SUPERIORS
@cppindex ECL_CLASS_INFERIORS
@cppindex ECL_CLASS_SLOTS
@cppindex ECL_CLASS_CPL
@cppindex ECL_INSTANCEP
@cppdef ECL_CLASS_OF
@cppdef ECL_SPEC_FLAG
@cppdef ECL_SPEC_OBJECT
@cppdef ECL_CLASS_NAME
@cppdef ECL_CLASS_SUPERIORS
@cppdef ECL_CLASS_INFERIORS
@cppdef ECL_CLASS_SLOTS
@cppdef ECL_CLASS_CPL
@cppdef ECL_INSTANCEP
@deftypefun cl_object ECL_CLASS_OF (cl_object x)
@deftypefunx cl_object ECL_SPEC_FLAG (cl_object x)
@ -791,10 +793,9 @@ interpreted. The objects of type @code{t_bytecodes} are implicitly
constructed by a call to eval, but can also be explicitly constructed
with the @code{si_make_lambda} function.
@anchor{si_safe_eval}
@cppindex si_safe_eval
@cppindex cl_safe_eval
@cppindex cl_eval
@cppdef si_safe_eval
@cppdef cl_safe_eval
@cppdef cl_eval
@defun si:safe-eval form env &optional err-value
@end defun
@deftypefun cl_object si_safe_eval (cl_narg narg, cl_object form, cl_object env, ...)
@ -827,7 +828,7 @@ si_safe_eval(3, form, ECL_NIL, ecl_make_fixnum(3)); /* on error function will re
@end example
@end deftypefun
@cppindex si_make_lambda
@cppdef si_make_lambda
@deftypefun cl_object si_make_lambda (cl_object name, cl_object def)
Builds an interpreted lisp function with name given by the symbol name
and body given by @code{def}.

View file

@ -5,9 +5,9 @@ To port ECL to a new architecture, the following steps are required:
@enumerate
@item Ensure that the GNU Multiprecision library supports this machine.
@item Ensure that the Boehm-Weiser garbage collector is supported by that architecture. Alternatively, port ECL's own garbage collector @code{src/c/alloc.d} and @code{src/c/gbc.d} to that platform.
@item Fix @code{src/aclocal.in}, @code{src/h/config.h.in} and @code{src/h/ecl.h} so that they supply flags for the new host machine.
@item Fix the machine dependent code in @code{src/c/}. The most critical parts are in the @code{unix*.d} and @code{thread*.d} files.
@item Ensure that the Boehm-Weiser garbage collector is supported by that architecture. Alternatively, port ECL's own garbage collector @file{src/c/alloc.d} and @file{src/c/gbc.d} to that platform.
@item Fix @file{src/aclocal.in}, @file{src/h/config.h.in} and @file{src/h/ecl.h} so that they supply flags for the new host machine.
@item Fix the machine dependent code in @file{src/c/}. The most critical parts are in the @file{unix*.d} and @file{thread*.d} files.
@item Compile as in any other platform.
@item Run the tests and compare to the results of other platforms.
@end enumerate

View file

@ -14,9 +14,9 @@
@subheading In-house DFFI
Commit @code{10bd3b613fd389da7640902c2b88a6e36088c920}. Native DFFI was
replaced by a @code{libffi} long time ago, but we have maintained the
code as a fallback. Due to small number of supported platforms and no
real use it has been removed in 2016.
replaced by a @url{https://sourceware.org/libffi/,libffi} long time ago,
but we have maintained the code as a fallback. Due to small number of
supported platforms and no real use it has been removed in 2016.
@c @node In-house GC
@subheading In-house GC

View file

@ -4,265 +4,263 @@
@subsection src/c
@multitable {aaaaaaaaaaaaaaa}{aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}
@item alloc_2.d
@item @file{alloc_2.d}
@tab memory allocation based on the Boehm GC
@item all_symbols.d
@item @file{all_symbols.d}
@tab name mangler and symbol initialization
@item apply.d
@item @file{apply.d}
@tab interface to C call mechanism
@item arch/*
@item @file{arch/*}
@tab architecture dependant code
@item array.d
@item @file{array.d}
@tab array routines
@item assignment.c
@item @file{assignment.c}
@tab assignment
@item backq.d
@item @file{backq.d}
@tab backquote mechanism
@item big.d
@item @file{big.d}
@tab bignum routines based on the GMP
@item big_ll.d
@item @file{big_ll.d}
@tab bignum emulation with long long
@item cfun.d
@item @file{cfun.d}
@tab compiled functions
@item cfun_dispatch.d
@item @file{cfun_dispatch.d}
@tab trampolines for functions
@item character.d
@item @file{character.d}
@tab character routines
@item char_ctype.d
@item @file{char_ctype.d}
@tab character properties.
@item cinit.d
@item @file{cinit.d}
@tab lisp initialization
@item clos/accessor.d
@item @file{clos/accessor.d}
@tab dispatch for slots
@item clos/cache.d
@item @file{clos/cache.d}
@tab thread-local cache for a variety of operations
@item clos/gfun.d
@item @file{clos/gfun.d}
@tab dispatch for generic functions
@item clos/instance.d
@item @file{clos/instance.d}
@tab CLOS interface
@item cmpaux.d
@item @file{cmpaux.d}
@tab auxiliaries used in compiled Lisp code
@item compiler.d
@item @file{compiler.d}
@tab bytecode compiler
@item cons.d
@item @file{cons.d}
@tab list manipulation macros & functions (auto generated)
@item disassembler.d
@item @file{disassembler.d}
@tab bytecodes disassembler utilities
@item dpp.c
@item @file{dpp.c}
@tab defun preprocessor
@item ecl_constants.h
@item @file{ecl_constants.h}
@tab constant values for all_symbols.d
@item ecl_features.h
@item @file{ecl_features.h}
@tab names of features compiled into ECL
@item error.d
@item @file{error.d}
@tab error handling
@item eval.d
@item @file{eval.d}
@tab evaluation
@item ffi/backtrace.d
@item @file{ffi/backtrace.d}
@tab C backtraces
@item ffi/cdata.d
@item @file{ffi/cdata.d}
@tab data for compiled files
@item ffi/libraries.d
@item @file{ffi/libraries.d}
@tab shared library and bundle opening / copying / closing
@item ffi/mmap.d
@item @file{ffi/mmap.d}
@tab mapping of binary files
@item ffi.d
@item @file{ffi.d}
@tab user defined data types and foreign functions interface
@item file.d
@item @file{file.d}
@tab file interface (implementation dependent)
@item format.d
@item @file{format.d}
@tab format (this isn't ANSI compliant, we need it for bootstrapping though)
@item hash.d
@item @file{hash.d}
@tab hash tables
@item interpreter.d
@item @file{interpreter.d}
@tab bytecode interpreter
@item iso_latin_names.h
@item @file{iso_latin_names.h}
@tab character names in ISO-LATIN-1
@item list.d
@item @file{list.d}
@tab list manipulating routines
@item load.d
@item @file{load.d}
@tab binary loader (contains also open_fasl_data)
@item macros.d
@item @file{macros.d}
@tab macros and environment
@item main.d
@item @file{main.d}
@tab ecl boot process
@item Makefile.in
@item @file{Makefile.in}
@tab Makefile for ECL core library
@item mapfun.d
@item @file{mapfun.d}
@tab mapping
@item multival.d
@item @file{multival.d}
@tab multiple values
@item newhash.d
@item @file{newhash.d}
@tab hashing routines
@item num_arith.d
@item @file{num_arith.d}
@tab arithmetic operations
@item number.d
@item @file{number.d}
@tab constructing numbers
@c these files need to be cleaned
@item numbers/*.d
@item @file{numbers/*.d}
@tab arithmetic operations (abs, atan, plusp etc)
@item num_co.d
@item @file{num_co.d}
@tab operations on floating-point numbers (implementation dependent)
@item num_log.d
@item @file{num_log.d}
@tab logical operations on numbers
@item num_pred.d
@item @file{num_pred.d}
@tab predicates on numbers
@item num_rand.d
@item @file{num_rand.d}
@tab random numbers
@item package.d
@item @file{package.d}
@tab packages (OS dependent)
@item pathname.d
@item @file{pathname.d}
@tab pathnames
@item predicate.d
@item @file{predicate.d}
@tab predicates
@item print.d
@item @file{print.d}
@tab print
@item printer/*.d
@item @file{printer/*.d}
@tab printer utilities and object representations
@item read.d
@item @file{read.d}
@tab reader
@item reader/parse_integer.d
@item reader/parse_number.d
@item @file{reader/parse_integer.d}
@item @file{reader/parse_number.d}
@item reference.d
@item @file{reference.d}
@tab reference in Constants and Variables
@item sequence.d
@item @file{sequence.d}
@tab sequence routines
@item serialize.d
@item @file{serialize.d}
@tab serialize a bunch of lisp data
@item sse2.d
@item @file{sse2.d}
@tab SSE2 vector type support
@item stacks.d
@item @file{stacks.d}
@tab binding/history/frame stacks
@item string.d
@item @file{string.d}
@tab string routines
@item structure.d
@item @file{structure.d}
@tab structure interface
@item symbol.d
@item @file{symbol.d}
@tab symbols
@item symbols_list.h
@item symbols_list2.h
@item @file{symbols_list.h}
@item @file{symbols_list2.h}
@tab The latter is generated from the first. The first has to contain all
symbols on the system which aren't local.
@item tcp.d
@item @file{tcp.d}
@tab stream interface to TCP
@item time.d
@item @file{time.d}
@tab time routines
@item typespec.d
@item @file{typespec.d}
@tab type specifier routines
@item unicode/*
@item @file{unicode/*}
@tab unicode definitions
@item unixfsys.d
@item @file{unixfsys.d}
@tab Unix file system interface
@item unixint.d
@item @file{unixint.d}
@tab Unix interrupt interface.
@item unixsys.d
@item @file{unixsys.d}
@tab Unix shell interface
@item vector_push.d
@item @file{vector_push.d}
@tab vector optimizations
@headitem threads/
@item atomic.d
@item @file{threads/atomic.d}
@tab atomic operations
@item barrier.d
@item @file{threads/barrier.d}
@tab wait barriers
@item condition_variable.d
@item @file{threads/condition_variable.d}
@tab condition variables for native threads
@c implement me: @code{mp_condition_variable_timedwait}
@item mailbox.d
@item @file{threads/mailbox.d}
@tab thread communication queue
@item mutex.d
@item @file{threads/mutex.d}
@tab mutually exclusive locks.
@item process.d
@item @file{threads/process.d}
@tab native threads
@item queue.d
@item @file{threads/queue.d}
@tab waiting queue for threads
@item rwlock.d
@item @file{threads/rwlock.d}
@tab POSIX read-write locks
@item semaphore.d
@item @file{threads/semaphore.d}
@tab POSIX-like semaphores
@end multitable

View file

@ -1,60 +1,108 @@
html { background: #FFF; }
/* colors */
@media (prefers-color-scheme: dark) {
/* dark theme */
html { color: seashell;
background: #1A1A1A; }
body { background: #1A1A1A; }
th { border-bottom: 2px solid lightgray; }
h1, h2, h3, h4, h5 { background-image: linear-gradient(to left, #202020, #3A3A3A); }
code, var, code a { color: darkorange;
background: #2A2A2A; }
a { color: seashell; }
pre { background: #2A2A2A;
color: seashell;
/* mark longer code block with stripe on the left */
border-left: 5px solid darkorange;
padding-left: 10px; }
pre.screen { background: #2A2A2A;
border: 1px solid lightgray; }
pre.programlisting { background: #2A2A2A;
border-left: 1px solid lightgray;
border-top: 1px solid lightgray; }
}
@media (prefers-color-scheme: light) {
/* light theme */
html { background: white }
body { background: white }
th { border-bottom: 2px solid gray; }
h1, h2, h3, h4, h5 { background: lightgray; }
code, var, code a { color: darkred;
background: whitesmoke; }
a { color: #000; }
pre { background: whitesmoke;
color: black;
/* mark longer code block with stripe on the left */
border-left: 5px solid darkred;
padding-left: 10px; }
pre.screen { background: #EEE;
border: 1px solid black; }
pre.programlisting { background: #EEEEEE;
border-left: 1px solid black;
border-top: 1px solid black; }
}
body {
margin: 1em 125px 0 10%;
line-height: 1.5em;
padding: 0 2em 1em 2em;
background: #FFF;
font: 12px Verdana,Arial, sans-serif
margin: 1em 125px 0 10%;
line-height: 1.5em;
padding: 0 2em 1em 2em;
font: 13px Verdana,Arial, sans-serif
}
ul, dd, dl, dt { margin-top: 0; margin-bottom: 0; }
p, code, td, dl, dt {
line-height: 1.5em;
line-height: 1.5em;
}
table {
font: inherit;
font: inherit;
border-collapse: collapse;
}
th, td {
vertical-align: top;
vertical-align: top;
}
h1, h2, h3, h4, h5 { background: #EEE; }
h1, h2, h3 { padding-left: 15px; }
h4, h5 { padding-left: 5px; }
code, pre {
font-size: 1em;
font-family: monospace;
font-size: 1em;
font-family: monospace;
}
code {
background: #CDC;
var {
font-size: 1em;
}
/* links inside code appear the same as the code itself */
code a {
font-weight: normal;
text-decoration: none;
}
/* but get an underline when hovering */
code a:hover {
text-decoration: underline;
}
/* ordinary links appear in bold */
a { font-weight: bold; }
pre.verbatim {
margin: 0 0 0 0;
margin: 0 0 0 0;
}
pre {
overflow: auto;
overflow: auto;
}
pre.screen {
font-weight: bold;
background: #EEE;
border: 1px solid black;
padding: 0.5em;
font-weight: bold;
padding: 0.5em;
}
pre.programlisting {
background: #EEEEEE;
border-left: 1px solid black;
border-top: 1px solid black;
padding: 0.5em;
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;
text-indent: -2em;
}
div.variablelist {
padding: 0 2em;
padding: 0 2em;
}
.type, .funcsynopsis, .symbol {
font-family: monospace;
font-family: monospace;
}
.type, .symbol, .replaceable {
white-space: nowrap;
white-space: nowrap;
}

View file

@ -5,9 +5,8 @@
* Compiling with ECL::
* Compiling with ASDF::
* C compiler configuration::
@c * Compiling with Matroska::
@end menu
@c * Compiling with Matroska::
@cindex System building
@cindex Creating executables and libraries
@ -20,7 +19,7 @@ programs. ECL is especially powerful on combining lisp programs with C
programs. You can embed ECL as a lisp engine in C programs, or call C
functions via @ref{Foreign Function Interface}. We explain file types
generated by some compilation approaches. For the examples,
a GNU/Linux system and gcc as a development environment are assumed.
a GNU/Linux system and gcc as a development environment are assumed.
You can generate the following files with ECL:
@ -97,7 +96,7 @@ bundles. FASC files are faster to compile, but generally slower to run.
If you want to make a library which is loaded dynamically from a lisp
program, you should choose the fasl file format. Under the hood native fasls
are just a shared library files.
are just shared library files.
This means you can load fasl files with @code{dlopen} and initialize it
by calling a init function from C programs, but this is not an intended
@ -113,7 +112,7 @@ Creating a fasl file from one lisp file is very easy.
To create a fasl file from more lisp files, firstly you have to compile
each lisp file into an object file, and then combine them with
c:build-fasl.
@code{c:build-fasl}.
@exindex Building native FASL
@lisp
@ -136,10 +135,11 @@ c:build-fasl.
@subsubsection Object file
Object files work as an intermediate file format. If you want to compile
more than two lisp files, you might better to compile with a :system-p t
option, which generates object files (instead of a fasl).
more than two lisp files, you might better to compile with a
@code{:system-p t} option, which generates object files (instead of a
fasl).
On linux systems, ECL invokes gcc -c to generate object files.
On linux systems, ECL invokes @code{gcc -c} to generate object files.
An object file consists of some functions in C:
@ -184,8 +184,8 @@ files act as intermediate files.
@subsubsection Static library
ECL can compile lisp programs to static libraries, which can be linked
with C programs. A static library is created by c:build-static-library
with some compiled object files.
with C programs. A static library is created by
@code{c:build-static-library} with some compiled object files.
@exindex Building static library
@lisp
@ -205,6 +205,7 @@ name of this function is specified by the @code{:init-name} option. In this
example, it is then @code{init_hello_goodbye}. The usage of this function is
shown below:
@cppdef ecl_init_module
@exindex Initializing static/shared library in C/C++
@example
@verbatim
@ -230,15 +231,15 @@ main(int argc, char **argv)
@end verbatim
@end example
Because the program itself does not know the type of the init
function, a prototype declaration is inserted. After booting up the
lisp environment, it invokes @code{init_hello_goodbye} via
@code{ecl_init_module}. @code{init_hello_goodbye} takes an argument, and
@code{ecl_init_module} supplies an appropriate one. Now that the
initialization is finished, we can use functions and other stuff
defined in the library.
Because the program itself does not know the type of the init function,
a prototype declaration is inserted. After booting up the lisp
environment, it invokes @code{init_hello_goodbye} via
@coderef{ecl_init_module}. @code{init_hello_goodbye} takes an argument,
and @coderef{ecl_init_module} supplies an appropriate one. Now that the
initialization is finished, we can use functions and other stuff defined
in the library.
@strong{DEPRECATED} @code{read_VV} - equivalent to @code{ecl_init_module}
@strong{DEPRECATED} @code{read_VV} - equivalent to @coderef{ecl_init_module}
@node Shared library
@subsubsection Shared library
@ -302,19 +303,20 @@ format. In case of @emph{Portable FASL} the bytecodes compiler is needed.
@subsection Compiling with ASDF
First, let's disregard the simple situation in which we write Lisp
without depending on any other Lisp libraries. A more practical
example is to build a library that depends on other asdf systems. ECL
provides a useful extension for asdf called @code{asdf:make-build},
which offers an abstraction for building libraries directly from
system definitions.
without depending on any other Lisp libraries. A more practical example
is to build a library that depends on other
@uref{https://common-lisp.net/project/asdf/,asdf}, systems. ECL provides
a useful extension for asdf called @code{asdf:make-build}, which offers
an abstraction for building libraries directly from system definitions.
To download dependencies you may use Quicklisp to load your system
(with dependencies defined). Make sure you can successfully load and
run your library in the ECL REPL (or @code{*slime-repl*}). Don't worry
about other libraries loaded in your image ECL will only build and
pack libraries your project depends on (that is, all dependencies you
put in your @code{.asd} file, and their dependencies - nothing more,
despite the fact that other libraries may be loaded).
To download dependencies you may use
@uref{https://www.quicklisp.org,Quicklisp} to load your system (with
dependencies defined). Make sure you can successfully load and run your
library in the ECL REPL (or @code{*slime-repl*}). Don't worry about
other libraries loaded in your image ECL will only build and pack
libraries your project depends on (that is, all dependencies you put in
your @code{.asd} file, and their dependencies - nothing more, despite
the fact that other libraries may be loaded).
@menu
* Example code to build::
@ -460,13 +462,13 @@ REPL):
:init-name "init_bt")
@end lisp
Note that we haven't specified @code{:monolithic t}, so we need to
build @code{bordeaux-threads} as well because @code{cl-fad} depends on
it. The building sequence doesn't matter and the resultant ~.so~ files
can also be used in your future programs if these libraries are not
Note that we haven't specified @code{:monolithic t}, so we need to build
@code{bordeaux-threads} as well because @code{cl-fad} depends on it. The
building sequence doesn't matter and the resultant @code{.so} files can
also be used in your future programs if these libraries are not
modified.
We need to initialize all these modules using @code{ecl_init_module}
We need to initialize all these modules using @coderef{ecl_init_module}
in the correct order. (@code{bordeaux-threads} must be initialized
before @code{cl-fad}; @code{cl-fad} and @code{alexandria} must be
initialized before @code{complex-ecample}.)
@ -520,9 +522,9 @@ This will show:
Factorial of 5 is: 120
@end example
Note we don't need to pass the current path in ~LD_LIBRARY_PATH~ here,
since our Lisp library is statically bundled with the executable. The
result is the same as the shared library example above. You can also
Note we don't need to pass the current path in @code{LD_LIBRARY_PATH}
here, since our Lisp library is statically bundled with the executable.
The result is the same as the shared library example above. You can also
build all dependent libraries separately as static libraries.
@node C compiler configuration

View file

@ -41,11 +41,13 @@ are the arguments that these routines expect, what are the calling
conventions and where are these routines to be found.
@end table
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 (Section 3.2, Section 3.3),
and of the higher level interface (Section 3.4). It is highly recommended that you read all
sections.
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{Two kinds
of FFI} and @ref{Foreign objects}), and of the higher level interface
(@xref{Higher level interfaces}). It is highly recommended that you read
all sections.
@node Two kinds of FFI
@subsection Two kinds of FFI
@ -112,8 +114,8 @@ section @emph{Supported Platforms} at
@ftindex DFFI
You can test if your copy of ECL was built with DFFI by inspecting
whether the symbol @var{:DFFI} is present in the list from variable
@var{*FEATURES*}.
whether the symbol @code{:dffi} is present in the list from variable
@code{*features*}.
@node Foreign objects
@subsection Foreign objects
@ -137,7 +139,7 @@ memory and deallocated when no longer in use.
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 (Section 3.4).
higher level interface (@xref{Higher level interfaces}).
The most important component of the object is the memory region where
data is stored. By default ECL assumes that the user will perform
@ -151,9 +153,9 @@ valid, ECL should not attempt to automatically destroy the object.
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 @var{NAME} is
automatically deallocated
@url{https://common-lisp.net/project/cffi/,CFFI} provide tools for doing
this. For instance, in the following example adapted from the UFFI
documentation, the string @var{name} is automatically deallocated
@lisp
(ffi:def-function ("gethostname" c-gethostname)
@ -180,10 +182,11 @@ version 1.8 (api for >=v2.0 is provided by cffi-uffi-compat system
shipped with CFFI). Code designed for UFFI library should run mostly
unchanged with ECL. Note, that api resides in ffi package, not uffi, to
prevent conflicts with cffi-uffi-compat. New code shouldn't use this
interface preferring CFFI.
interface preferring @url{https://common-lisp.net/project/cffi/,CFFI}.
@item
The CFFI library features a complete backend for ECL. This method of
interfacing with the foreign libraries is preferred over using UFFI.
The @url{https://common-lisp.net/project/cffi/,CFFI} library features a
complete backend for ECL. This method of interfacing with the foreign
libraries is preferred over using UFFI.
@item
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 mix
@ -208,7 +211,7 @@ You need to specify the libraries you use and do it at the toplevel, so
that the compiler may include them at link time.
@item
Every function you will use has to be declared using
@code{ffi:def-function}.
@coderef{ffi:def-function}.
@end itemize
@lisp
@ -239,9 +242,10 @@ Build and load this module with (compile-file "uffi.lsp" :load t)
@subsubheading CFFI example
@exindex CFFI usage
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 homepage, download the
code and build it using ASDF.
The @url{https://common-lisp.net/project/cffi/,CFFI} library is an
independent project and it is not shipped with ECL. If you wish to use
it you can go to their homepage, download the code and build it using
ASDF.
CFFI differs slightly from UFFI in that functions may be used even
without being declared beforehand.
@ -280,7 +284,7 @@ Build and load this module with (compile-file "cffi.lsp" :load t)
@exindex SFFI usage
To compare with the previous pieces of code, we show how the previous programs would be
written using @code{ffi:clines} and @code{ffi:c-inline}.
written using @coderef{ffi:clines} and @coderef{ffi:c-inline}.
@lisp
#|

View file

@ -4,6 +4,6 @@
@lspindex ffi:*use-dffi*
@defvr Variable {ffi:*use-dffi*}
This variable controls whether @code{DFFI} is used or not.
This variable controls whether DFFI is used or not.
@end defvr

View file

@ -5,7 +5,7 @@
@subsubheading Reference
@lspindex ffi:clines
@lspdef ffi:clines
@defspec ffi:clines c/c++-code*
Insert C declarations and definitions
@ -17,25 +17,25 @@ One or more strings with C definitions. Not evaluated.
No value.
@end table
@subsubheading Description
@paragraph Description
This special form inserts C code from strings passed in the
@var{arguments} directly in the file that results from compiling lisp
sources. Contrary to @code{ffi:c-inline}, this function may have no
sources. Contrary to @coderef{ffi:c-inline}, this function may have no
executable statements, accepts no input value and returns no value.
The main use of @code{ffi:clines} is to declare or define C variables
The main use of @coderef{ffi:clines} is to declare or define C variables
and functions that are going to be used later in other FFI
statements. All statements from @var{arguments} are grouped at the
beginning of the produced header file.
@code{ffi:clines} is a special form that can only be used in lisp
@coderef{ffi:clines} 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 the compilation time or when loading the
file.
@subsubheading Examples
@exindex @code{ffi:clines} adding c toplevel declarations
In this example the @code{ffi:clines} statement is required to get
@paragraph Examples
@exindex @coderef{ffi:clines} adding c toplevel declarations
In this example the @coderef{ffi:clines} statement is required to get
access to the C function @code{cos}:
@lisp
(ffi:clines "#include <math.h>")
@ -44,7 +44,7 @@ access to the C function @code{cos}:
@end lisp
@end defspec
@lspindex ffi:c-inline
@lspdef ffi:c-inline
@defspec ffi:c-inline (lisp-values) (arg-c-types) return-type c/c++-code @
&key (side-effects t) (one-liner nil)
@ -56,20 +56,20 @@ One or more lisp expressions. Evaluated.
@item arg-c-types
One or more valid FFI types. Evaluated.
@item return-type
Valid FFI type or (VALUES ffi-type*).
Valid FFI type or @code{(values ffi-type*)}.
@item c/c++-code
String containing valid C code plus some valid escape forms.
@item one-liner
Boolean indicating, if the expression is a valid R-value. Defaults to
@code{NIL}.
@code{nil}.
@item side-effects
Boolean indicating, if the expression causes side effects. Defaults to
@code{T}.
@code{t}.
@item returns
One or more lisp values.
@end table
@subsubheading Description
@paragraph Description
This is a 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.
@ -86,16 +86,16 @@ mixes C expressions with two kind of escape forms.
The first kind of escape form are made of a hash and a letter or a
number, as in: @code{#0}, @code{#1}, ..., until @code{#z}. These codes
are replaced by the corresponding input values. The second kind of
escape form has the format @verb{|@(return [n])|}, it can be used as
escape form has the format @code{@@(return [n])}, it can be used as
lvalue in a C expression and it is used to set the n-th output value of
the @code{ffi:c-inline} form.
the @coderef{ffi:c-inline} form.
When the parameter @var{one-liner} is true, then the C template must be
a simple C statement that outputs a value. In this case the use of
@verb{|@(return)|} is not allowed. When the parameter @var{one-liner} is
@code{@@(return)} is not allowed. When the parameter @var{one-liner} 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 @verb{|@(return)|}.
the output of the form can only be set using @code{@@(return)}.
Parameter @var{side-effects} set to false will indicate, that the
functions causes no side-effects. This information is used by the
@ -104,11 +104,11 @@ false, but the function may cause the side effects, then results are
undefined.
Note that the conversion between lisp arguments and FFI types is
automatic. Note also that @code{ffi:c-inline} cannot be used in
automatic. Note also that @coderef{ffi:c-inline} cannot be used in
interpreted or bytecompiled code! Such usage will signal an error.
@subsubheading Examples
@exindex @code{ffi:c-inline} inlining c code
@paragraph Examples
@exindex @coderef{ffi:c-inline} inlining c code
The following example implements the transcendental function SIN using
the C equivalent:
@ -121,7 +121,7 @@ the C equivalent:
:side-effects nil))
@end lisp
This function can also be implemented using the @verb{|@(return)|} form
This function can also be implemented using the @code{@@(return)} form
as follows:
@lisp
@ -136,7 +136,7 @@ as follows:
The following example is slightly more complicated as it involves loops
and two output values:
@exindex @code{ffi:c-inline} returning multiple values
@exindex @coderef{ffi:c-inline} returning multiple values
@lisp
@verbatim
(defun sample (x)
@ -155,7 +155,7 @@ and two output values:
@end lisp
@end defspec
@lspindex ffi:c-progn
@lspdef ffi:c-progn
@defspec ffi:c-progn args &body body
Interleave C statements with the Lisp code
@ -167,14 +167,14 @@ Lisp arguments. Evaluated.
No value.
@end table
@subsubheading Description
@paragraph Description
This form is used for it's side effects. It allows for interleaving C
statements with the Lisp code. The argument types doesn't have to be
declared in such case the objects type in the C world will be
@code{cl_object}.
@subsubheading Examples
@exindex @code{ffi:c-progn} interleaving c and lisp code
@paragraph Examples
@exindex @coderef{ffi:c-progn} interleaving c and lisp code
@lisp
@verbatim
(lambda (i)
@ -195,7 +195,7 @@ declared in such case the objects type in the C world will be
@c XXX: SFFI returns one-element list pointer, while DFFI returns just a
@c pointer. This is probably a bug.
@lspindex ffi:defcallback
@lspdef ffi:defcallback
@defspec ffi:defcallback name ret-type arg-desc &body body
@table @var
@ -211,13 +211,13 @@ Function body.
Pointer to the defined callback.
@end table
@subsubheading Description
@paragraph Description
Defines Lisp function and generates a callback for the C world, which
may be passed to these functions. Note, that this special operator has
also a dynamic variant (with the same name and interface).
@end defspec
@lspindex ffi:defcbody
@lspdef ffi:defcbody
@defmac ffi:defcbody name arg-types result-type c-expression
Define C function under the lisp name
@ -233,16 +233,16 @@ Result type of the C function (may be @code{(values ...)}.
Defined function name.
@end table
@subsubheading Description
The compiler defines a Lisp function named by @var{NAME} whose body
consists of the C code of the string @var{C-EXPRESSION}. In the
@var{C-EXPRESSION} one can reference the arguments of the function as
@paragraph Description
The compiler defines a Lisp function named by @var{name} whose body
consists of the C code of the string @var{c-expression}. In the
@var{c-expression} one can reference the arguments of the function as
@code{#0}, @code{#1}, etc.
The interpreter ignores this form.
@end defmac
@lspindex ffi:defentry
@lspdef ffi:defentry
@defmac ffi:defentry name arg-types c-name &key no-interrupts
@table @var
@ -253,26 +253,26 @@ Lisp name for the function.
Argument types of the C function.
@item c-name
If @var{C-NAME} is a list, then C function result type is declared as
@code{(CAR C-NAME)} and its name is @code{(STRING (CDR C-NAME))}.
If @var{c-name} is a list, then C function result type is declared as
@code{(car c-name)} and its name is @code{(string (cdr c-name))}.
If it's an atom, then the result type is @code{:OBJECT}, and function
name is @code{(STRING C-NAME)}.
If it's an atom, then the result type is @code{:object}, and function
name is @code{(string c-name)}.
@item returns
Lisp function @code{NAME}.
Lisp function @code{name}.
@end table
@subsubheading Description
The compiler defines a Lisp function named by @var{NAME} whose body
@paragraph Description
The compiler defines a Lisp function named by @var{name} whose body
consists of a calling sequence to the C language function named by
@var{C-NAME}.
@var{c-name}.
The interpreter ignores this form.
@end defmac
@c XXX> note sure if this works
@c @subsubheading @code{definline}
@c @paragraph @code{definline}
@c @lspindex ffi:definline
@c @defmac ffi:definline fun arg-types result-type code
@c @table @var
@ -283,24 +283,24 @@ The interpreter ignores this form.
@c @end table
@c @end defmac
@c @subsubheading Description
@c @paragraph Description
@c DEFINLINE behaves like a DEFCBODY (see), but also instructs the LISP
@c compiler to expand inline any call to function SYMBOL into code
@c corresponding to the C language expression C/C++-CODE, whenever it can
@c determine that the actual arguments are of the specified type.
@c <XXX
@lspindex ext:with-backend
@lspdef ext:with-backend
@defspec ext:with-backend &key bytecodes c/c++
Use different code depending on the backend.
@subsubheading Description
@paragraph Description
Depending on whether the bytecodes or C compiler is used, this form will
emit the code given in the corresponding keyword argument.
@subsubheading Examples
@exindex @code{ext:with-backend} use different code for c and bytecodes compiler
@paragraph Examples
@exindex @coderef{ext:with-backend} use different code for c and bytecodes compiler
@verbatim
CL-USER> (defmacro test ()
'(ext:with-backend :c/c++ "c/c++" :bytecodes "bytecodes"))
@ -315,12 +315,13 @@ CL-USER> (funcall (compile nil (lambda () (test))))
@end verbatim
@end defspec
@lspindex ffi:defla
@lspdef ffi:defla
@defmac ffi:defla name args &body body
Provide Lisp alternative for interpreted code.
@subsubheading Description
Used to DEFine Lisp Alternative. For the interpreter, DEFLA is equivalent to
DEFUN, but the compiler ignores this form.
@paragraph Description
Used to DEFine Lisp Alternative. For the interpreter,
@coderef{ffi:defla} is equivalent to @code{defun}, but the compiler
ignores this form.
@end defmac

View file

@ -101,7 +101,7 @@ A generic lisp object (i.e. a @code{cl_object} in C)
@subsubheading Reference
@lspindex ffi:def-constant
@lspdef ffi:def-constant
@defmac ffi:def-constant name value &key (export nil)
Binds a symbol to a constant.
@ -112,30 +112,30 @@ A symbol that will be bound to the value.
@item value
An evaluated form that is bound the the name.
@item export
When @code{T}, the name is exported from the current package. Defaults
to @code{NIL}.
When @code{t}, the name is exported from the current package. Defaults
to @code{nil}.
@item returns
Constant name.
@end table
@subsubheading Description
@paragraph Description
This is a thin wrapper around @code{defconstant}. It evaluates at
compile-time and optionally exports the symbol from the package.
@subsubheading Examples
@exindex @code{ffi:def-constant} defining constants
@paragraph Examples
@exindex @coderef{ffi:def-constant} defining constants
@lisp
(ffi:def-constant pi2 (* 2 pi))
(ffi:def-constant exported-pi2 (* 2 pi) :export t)
@end lisp
@subsubheading Side Effects
@paragraph Side Effects
Creates a new special variable.
@end defmac
@lspindex ffi:def-foreign-type
@lspdef ffi:def-foreign-type
@defmac ffi:def-foreign-type name definition
Defines a new foreign type
@ -149,24 +149,24 @@ A form that is not evaluated that defines the new foreign type.
Foreign type designator (@var{value}).
@end table
@subsubheading Description
@paragraph Description
Defines a new foreign type
@subsubheading Examples
@exindex @code{ffi:def-foreign-type} examples
@paragraph Examples
@exindex @coderef{ffi:def-foreign-type} examples
@lisp
(ffi:def-foreign-type my-generic-pointer :pointer-void)
(ffi:def-foreign-type a-double-float :double-float)
(ffi:def-foreign-type char-ptr (* :char))
@end lisp
@subsubheading Side effects
@paragraph Side effects
Defines a new foreign type.
@end defmac
@lspindex ffi:null-char-p
@lspdef ffi:null-char-p
@defun ffi:null-char-p char
Tests a character for NULL value
@ -178,13 +178,13 @@ A character or integer.
A boolean flag indicating if @var{char} is a NULL value.
@end table
@subsubheading Description
@paragraph Description
A predicate testing if a character or integer is NULL. This abstracts
the difference in implementations where some return a character and some
return a integer whence dereferencing a C character pointer.
@subsubheading Examples
@exindex @code{ffi:null-char-p} example
@paragraph Examples
@exindex @coderef{ffi:null-char-p} example
@lisp
(ffi:def-array-pointer ca :unsigned-char)
(let ((fs (ffi:convert-to-foreign-string "ab")))
@ -205,7 +205,7 @@ Aggregate types are comprised of one or more primitive types.
@subsubheading Reference
@lspindex ffi:def-enum
@lspdef ffi:def-enum
@defmac ffi:def-enum name fields &key separator-string
Defines a C enumeration
@ -224,15 +224,15 @@ set to 1+ this value.
A string that governs the creation of constants. The default is "#".
@end table
@subsubheading Description
@paragraph Description
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 concatenation of the enumeration name,
separator-string, and field symbol. Also creates a foreign type with the
name name of type @code{:int}.
@subsubheading Examples
@exindex @code{ffi:def-enum} sample enumerations
@paragraph Examples
@exindex @coderef{ffi:def-enum} sample enumerations
@lisp
(ffi:def-enum abc (:a :b :c))
;; Creates constants abc#a (1), abc#b (2), abc#c (3) and defines
@ -243,12 +243,13 @@ name name of type @code{:int}.
;; the foreign type efoo to be :int
@end lisp
@subsubheading Side effects
@paragraph Side effects
Creates a @code{:int} foreign type, defines constants.
@end defmac
@lspdef ffi:def-struct
@defmac ffi:def-struct name &rest fields
Defines a C structure
@ -261,13 +262,13 @@ A variable number of field definitions. Each definition is a list
consisting of a symbol naming the field followed by its foreign type.
@end table
@subsubheading Description
@paragraph Description
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 @code{:pointer-self}.
@subsubheading Examples
@exindex @code{ffi:def-struct} defining C structure
@paragraph Examples
@exindex @coderef{ffi:def-struct} defining C structure
@lisp
(ffi:def-struct foo (a :unsigned-int)
(b (* :char))
@ -275,13 +276,13 @@ structure. It's type is @code{:pointer-self}.
(next :pointer-self))
@end lisp
@subsubheading Side effects
@paragraph Side effects
Creates a foreign type.
@end defmac
@lspindex ffi:get-slot-value
@lspdef ffi:get-slot-value
@defun ffi:get-slot-value obj type field
Retrieves a value from a slot of a structure
@ -294,15 +295,15 @@ The name of the foreign structure.
@item field
The name of the desired field in the foreign structure.
@item returns
The value of the @code{field} in the structure @code{obj}.
The value of the @var{field} in the structure @var{obj}.
@end table
@subsubheading Description
@paragraph Description
Accesses a slot value from a structure. This is generalized and can be
used with @code{setf}.
@subsubheading Examples
@exindex @code{ffi:get-slot-value} manipulating a struct field
@paragraph Examples
@exindex @coderef{ffi:get-slot-value} manipulating a struct field
@lisp
(ffi:get-slot-value foo-ptr 'foo-structure 'field-name)
(setf (ffi:get-slot-value foo-ptr 'foo-structure 'field-name) 10)
@ -311,7 +312,7 @@ used with @code{setf}.
@lspindex ffi:get-slot-pointer
@lspdef ffi:get-slot-pointer
@defun ffi:get-slot-pointer obj type field
Retrieves a pointer from a slot of a structure
@ -327,12 +328,12 @@ The name of the desired field in the foreign structure.
The value of the pointer @var{field} in the structure @var{obj}.
@end table
@subsubheading Description
This is similar to @code{get-slot-value}. It is used when the value of
a slot is a pointer type.
@paragraph Description
This is similar to @coderef{ffi:get-slot-value}. It is used when the
value of a slot is a pointer type.
@subsubheading Examples
@exindex @code{ffi:get-slot-value} usage
@paragraph Examples
@exindex @coderef{ffi:get-slot-value} usage
@lisp
(ffi:get-slot-pointer foo-ptr 'foo-structure 'my-char-ptr)
@end lisp
@ -340,7 +341,7 @@ a slot is a pointer type.
@lspindex ffi:def-array-pointer
@lspdef ffi:def-array-pointer
@defmac ffi:def-array-pointer name type
Defines a pointer to an array of @var{type}
@ -352,22 +353,22 @@ A name of the new foreign type.
The foreign type of the array elements.
@end table
@subsubheading Description
@paragraph Description
Defines a type that is a pointer to an array of @var{type}.
@subsubheading Examples
@exindex @code{ffi:def-array-pointer} usage
@paragraph Examples
@exindex @coderef{ffi:def-array-pointer} usage
@lisp
(ffi:def-array-pointer byte-array-pointer :unsigned-char)
@end lisp
@subsubheading Side effects
@paragraph Side effects
Defines a new foreign type.
@end defmac
@lspindex ffi:deref-array
@lspdef ffi:deref-array
@defun ffi:deref-array array type position
Dereference an array
@ -383,24 +384,24 @@ An integer specifying the position to retrieve from the @var{array}.
The value stored in the @var{position} of the @var{array}.
@end table
@subsubheading Description
@paragraph Description
Dereferences (retrieves) the value of the foreign array
element. @code{setf}-able.
@subsubheading Examples
@exindex @code{ffi:deref-array} retrieving array element
@paragraph Examples
@exindex @coderef{ffi:deref-array} retrieving array element
@lisp
(ffi:def-array-pointer ca :char)
(let ((fs (ffi:convert-to-foreign-string "ab")))
(values (ffi:null-char-p (ffi:deref-array fs 'ca 0))
(ffi:null-char-p (ffi:deref-array fs 'ca 2))))
;; => NIL T
@lisp
@end lisp
@end defun
@lspindex ffi:def-union
@lspdef ffi:def-union
@defmac ffi:def-union name &rest fields
Defines a foreign union type
@ -412,11 +413,11 @@ A name of the new union type.
A list of fields of the union in form @code{(field-name field-type)}.
@end table
@subsubheading Description
@paragraph Description
Defines a foreign union type.
@subsubheading Examples
@exindex @code{ffi:def-union} union definition and usage
@paragraph Examples
@exindex @coderef{ffi:def-union} union definition and usage
@lisp
(ffi:def-union test-union
(a-char :char)
@ -430,7 +431,7 @@ Defines a foreign union type.
;; => #\A
@end lisp
@subsubheading Side effects
@paragraph Side effects
Defines a new foreign type.
@end defmac
@ -444,7 +445,7 @@ can be freed.
@subsubheading Reference
@lspindex ffi:allocate-foreign-object
@lspdef ffi:allocate-foreign-object
@defun ffi:allocate-foreign-object type &optional size
Allocates an instance of a foreign object
@ -460,12 +461,12 @@ parameter is evaluated.
A pointer to the foreign object.
@end table
@subsubheading Description
@paragraph Description
Allocates an instance of a foreign object. It returns a pointer to the
object.
@subsubheading Examples
@exindex @code{ffi:allocate-foreign-object} allocating structure object
@paragraph Examples
@exindex @coderef{ffi:allocate-foreign-object} allocating structure object
@lisp
(ffi:def-struct ab (a :int) (b :double))
;; => (:STRUCT (A :INT) (B :DOUBLE))
@ -474,7 +475,7 @@ object.
@end lisp
@end defun
@lspindex ffi:free-foreign-object
@lspdef ffi:free-foreign-object
@defun ffi:free-foreign-object ptr
Frees memory that was allocated for a foreign object
@ -484,11 +485,11 @@ Frees memory that was allocated for a foreign object
A pointer to the allocated foreign object to free.
@end table
@subsubheading Description
@paragraph Description
Frees memory that was allocated for a foreign object.
@end defun
@lspindex ffi:with-foreign-object
@lspdef ffi:with-foreign-object
@defmac ffi:with-foreign-object (var type) &body body
Wraps the allocation, binding and destruction of a foreign object around
@ -505,12 +506,12 @@ Code to be evaluated.
The result of evaluating the body.
@end table
@subsubheading Description
@paragraph Description
This function wraps the allocation, binding, and destruction of a
foreign object around the body of code.
@subsubheading Examples
@exindex @code{ffi:with-foreign-object} macro usage
@paragraph Examples
@exindex @coderef{ffi:with-foreign-object} macro usage
@lisp
(defun gethostname2 ()
"Returns the hostname"
@ -521,7 +522,7 @@ foreign object around the body of code.
@end lisp
@end defmac
@lspindex ffi:size-of-foreign-type
@lspdef ffi:size-of-foreign-type
@defmac ffi:size-of-foreign-type ftype
Returns the number of data bytes used by a foreign object type
@ -533,12 +534,12 @@ A foreign type specifier. This parameter is evaluated.
Number of data bytes used by a foreign object @var{ftype}.
@end table
@subsubheading Description
@paragraph Description
Returns the number of data bytes used by a foreign object type. This
does not include any Lisp storage overhead.
@subsubheading Examples
@exindex @code{ffi:size-of-foreign-type}
@paragraph Examples
@exindex @coderef{ffi:size-of-foreign-type}
@lisp
(ffi:size-of-foreign-type :unsigned-byte)
;; => 1
@ -547,7 +548,7 @@ does not include any Lisp storage overhead.
@end lisp
@end defmac
@lspindex ffi:pointer-address
@lspdef ffi:pointer-address
@defun ffi:pointer-address ptr
Returns the address of a pointer
@ -559,11 +560,11 @@ A pointer to a foreign object.
An integer representing the pointer's address.
@end table
@subsubheading Description
@paragraph Description
Returns the address as an integer of a pointer.
@end defun
@lspindex ffi:deref-pointer
@lspdef ffi:deref-pointer
@defun ffi:deref-pointer ptr ftype
Dereferences a pointer
@ -577,15 +578,16 @@ Foreign type of the object being pointed to.
The value of the object where the pointer points.
@end table
@subsubheading Description
@paragraph Description
Returns the object to which a pointer points. @code{setf}-able.
@subsubheading Notes
Casting of the pointer may be performed with @code{with-cast-pointer}
together with the @code{deref-pointer}/@code{deref-array}.
@paragraph Notes
Casting of the pointer may be performed with
@coderef{ffi:with-cast-pointer} together with
@coderef{ffi:deref-pointer}/@coderef{ffi:deref-array}.
@subsubheading Examples
@exindex @code{ffi:deref-pointer}
@paragraph Examples
@exindex @coderef{ffi:deref-pointer}
@lisp
(let ((intp (ffi:allocate-foreign-object :int)))
(setf (ffi:deref-pointer intp :int) 10)
@ -596,7 +598,7 @@ together with the @code{deref-pointer}/@code{deref-array}.
@end lisp
@end defun
@lspindex ffi:ensure-char-character
@lspdef ffi:ensure-char-character
@defun ffi:ensure-char-character object
Ensures that a dereferenced @code{:char} pointer is a character
@ -608,12 +610,12 @@ Either a character or a integer specifying a character code.
A character.
@end table
@subsubheading Description
@paragraph Description
Ensures that an objects obtained by dereferencing @code{:char} and
@code{:unsigned-char} pointers is a lisp character.
@subsubheading Examples
@exindex @code{ffi:ensure-char-character}
@paragraph Examples
@exindex @coderef{ffi:ensure-char-character}
@lisp
(let ((fs (ffi:convert-to-foreign-string "a")))
(prog1
@ -622,12 +624,12 @@ Ensures that an objects obtained by dereferencing @code{:char} and
;; => #\a
@end lisp
@subsubheading Exceptional Situations
@paragraph Exceptional Situations
Depending upon the implementation and what UFFI expects, this macro may
signal an error if the object is not a character or integer.
@end defun
@lspindex ffi:ensure-char-integer
@lspdef ffi:ensure-char-integer
@defun ffi:ensure-char-integer object
Ensures that a dereferenced @code{:char} pointer is an integer
@ -639,12 +641,12 @@ Either a character or a integer specifying a character code.
An integer.
@end table
@subsubheading Description
@paragraph Description
Ensures that an objects obtained by dereferencing @code{:char} and
@code{:unsigned-char} pointers is a lisp integer.
@subsubheading Examples
@exindex @code{ffi:ensure-char-integer}
@paragraph Examples
@exindex @coderef{ffi:ensure-char-integer}
@lisp
(let ((fs (ffi:convert-to-foreign-string "a")))
(prog1
@ -653,12 +655,12 @@ Ensures that an objects obtained by dereferencing @code{:char} and
;; => 96
@end lisp
@subsubheading Exceptional Situations
@paragraph Exceptional Situations
Depending upon the implementation and what UFFI expects, this macro may
signal an error if the object is not a character or integer.
@end defun
@lspindex ffi:make-null-pointer
@lspdef ffi:make-null-pointer
@defun ffi:make-null-pointer ftype
Create a NULL pointer of a specified type
@ -671,7 +673,7 @@ The NULL pointer of type @var{ftype}.
@end table
@end defun
@lspindex ffi:null-pointer-p
@lspdef ffi:null-pointer-p
@defun ffi:null-pointer-p ptr
Tests a pointer for NULL value
@ -684,13 +686,13 @@ The boolean flag.
@end table
@end defun
@lspindex ffi:+null-cstring-pointer+
@lspdef ffi:+null-cstring-pointer+
@defvr Variable {ffi:+null-cstring-pointer+}
A NULL cstring pointer. This can be used for testing if a cstring
returned by a function is NULL.
@end defvr
@lspindex ffi:with-cast-pointer
@lspdef ffi:with-cast-pointer
@defmac ffi:with-cast-pointer (var ptr ftype) &body body
Wraps a body of code with a pointer cast to a new type
@ -706,13 +708,13 @@ A foreign type of the object being pointed to.
The value of the object where the pointer points.
@end table
@subsubheading Description
@paragraph Description
Executes @var{body} with @var{ptr} cast to be a pointer to type
@var{ftype}. @var{var} will be bound to this value during the
execution of @var{body}.
@subsubheading Examples
@exindex @code{ffi:with-cast-pointer}
@paragraph Examples
@exindex @coderef{ffi:with-cast-pointer}
@lisp
(ffi:with-foreign-object (size :int)
;; FOO is a foreign function returning a :POINTER-VOID
@ -727,7 +729,7 @@ execution of @var{body}.
@end lisp
@end defmac
@lspindex ffi:def-foreign-var
@lspdef ffi:def-foreign-var
@defmac ffi:def-foreign-var name type module
Defines a symbol macro to access a variable in foreign code
@ -745,15 +747,15 @@ A foreign type of the foreign variable.
@item module
Either a string specifying the module (or library) the foreign
variable resides in, @code{:default} if no module needs to be loaded
or @code{NIL} to use SFFI.
or @code{nil} to use SFFI.
@end table
@subsubheading Description
@paragraph Description
Defines a symbol macro which can be used to access (get and set) the
value of a variable in foreign code.
@subsubheading Examples
@exindex @code{ffi:def-foreign-var} places in foreign world
@paragraph Examples
@exindex @coderef{ffi:def-foreign-var} places in foreign world
C code defining foreign structure, standalone integer and the accessor:
@example
@ -867,7 +869,7 @@ an example of handling such a function.
@subsubheading Reference
@lspindex ffi:convert-from-cstring
@lspdef ffi:convert-from-cstring
@defmac ffi:convert-from-cstring object
Converts a @code{cstring} to a Lisp string
@table @var
@ -877,12 +879,12 @@ A @code{cstring}
A Lisp string
@end table
@subsubheading Description
@paragraph Description
Converts a Lisp string to a cstring. This is most often used when
processing the results of a foreign function that returns a cstring.
@end defmac
@lspindex ffi:convert-to-cstring
@lspdef ffi:convert-to-cstring
@defmac ffi:convert-to-cstring object
Converts a Lisp string to a @code{cstring}
@table @var
@ -892,28 +894,28 @@ A Lisp string
A @code{cstring}
@end table
@subsubheading Description
@paragraph Description
Converts a Lisp string to a @code{cstring}. The @code{cstring} should
be freed with @code{free-cstring}.
@subsubheading Side Effects
be freed with @coderef{ffi:free-cstring}.
@paragraph Side Effects
This function allocates memory.
@end defmac
@lspindex ffi:free-cstring
@lspdef ffi:free-cstring
@defmac ffi:convert-from-cstring cstring
Free memory used by @var{cstring}
@table @var
@item cstring
@code{cstring} to be freed.
@end table
@subsubheading Description
Frees any memory possibly allocated by @code{convert-to-cstring}. On ECL, a
@code{cstring} is just the Lisp string itself.
@paragraph Description
Frees any memory possibly allocated by @coderef{ffi:convert-to-cstring}.
On ECL, a @code{cstring} is just the Lisp string itself.
@end defmac
@lspindex ffi:with-cstring
@lspdef ffi:with-cstring
@defmac ffi:with-cstring (cstring string) &body body
Binds a newly created @code{cstring}
@table @var
@ -926,10 +928,10 @@ The body of where the @var{cstring} will be bound.
@item returns
Result of evaluating the @var{body}.
@end table
@subsubheading Description
@paragraph Description
Binds a symbol to a @code{cstring} created from conversion of a
@var{string}. Automatically frees the @var{cstring}.
@subsubheading Examples
@paragraph Examples
@exindex @code{with-cstring}
@lisp
(ffi:def-function ("getenv" c-getenv)
@ -944,7 +946,7 @@ Binds a symbol to a @code{cstring} created from conversion of a
@end lisp
@end defmac
@lspindex ffi:with-cstrings
@lspdef ffi:with-cstrings
@defmac ffi:with-cstrings bindings &body body
Binds a newly created @code{cstrings}
@table @var
@ -956,13 +958,13 @@ The body of where the @var{bindings} will be bound.
@item returns
Result of evaluating the @var{body}.
@end table
@subsubheading Description
@paragraph Description
Binds a symbols to a @code{cstring}s created from conversion of a
@var{string}s. Automatically frees the @var{cstring}s. This macro works
similar to @code{let*}. Based on @code{with-cstring}.
@end defmac
@lspindex ffi:convert-from-foreign-string
@lspdef ffi:convert-from-foreign-string
@defmac ffi:convert-from-foreign-string foreign-string &key length (null-terminated-p t)
Converts a foreign string into a Lisp string
@table @var
@ -972,17 +974,17 @@ A foreign string.
The length of the foreign string to convert. The default is the length
of the string until a NULL character is reached.
@item null-terminated-p
A boolean flag with a default value of @code{T}. When true, the string is
A boolean flag with a default value of @code{t}. When true, the string is
converted until the first NULL character is reached.
@item returns
A Lisp string.
@end table
@subsubheading Description
@paragraph Description
Returns a Lisp string from a foreign string. Can translate ASCII and
binary strings.
@end defmac
@lspindex ffi:convert-to-foreign-string
@lspdef ffi:convert-to-foreign-string
@defmac ffi:convert-to-foreign-string string
Converts a Lisp string to a foreign string
@table @var
@ -991,29 +993,29 @@ A Lisp string.
@item returns
A foreign string.
@end table
@subsubheading Description
@paragraph Description
Converts a Lisp string to a foreign string. Memory should be freed with
@code{free-foreign-object}.
@coderef{ffi:free-foreign-object}.
@end defmac
@lspindex ffi:allocate-foreign-string
@lspdef ffi:allocate-foreign-string
@defmac ffi:allocate-foreign-string size &key unsigned
Allocates space for a foreign string
@table @var
@item size
The size of the space to be allocated in bytes.
@item unsigned
A boolean flag with a default value of @code{T}. When true, marks the pointer
A boolean flag with a default value of @code{t}. When true, marks the pointer
as an @code{:unsigned-char}.
@item returns
A foreign string which has undefined contents.
@end table
@subsubheading Description
@paragraph Description
Allocates space for a foreign string. Memory should be freed with
@code{free-foreign-object}.
@coderef{ffi:free-foreign-object}.
@end defmac
@lspindex ffi:with-foreign-string
@lspdef ffi:with-foreign-string
@defmac ffi:with-foreign-string (foreign-string string) &body body
Binds a newly allocated @code{foreign-string}
@table @var
@ -1026,13 +1028,13 @@ The body of where the @var{foreign-string} will be bound.
@item returns
Result of evaluating the @var{body}.
@end table
@subsubheading Description
@paragraph Description
Binds a symbol to a @code{foreign-string} created from conversion of a
@var{string}. Automatically deallocates the @var{foreign-string}.
@subsubheading Examples
@paragraph Examples
@end defmac
@lspindex ffi:with-foreign-strings
@lspdef ffi:with-foreign-strings
@defmac ffi:with-foreign-strings bindings &body body
Binds a newly created @code{foreign string}
@table @var
@ -1045,10 +1047,10 @@ The body of where the @var{bindings} will be bound.
@item returns
Result of evaluating the @var{body}.
@end table
@subsubheading Description
@paragraph Description
Binds a symbols to a @code{foreign-string}s created from conversion of a
@var{string}s. Automatically frees the @var{foreign-string}s. This macro
works similar to @code{let*}. Based on @code{with-foreign-string}.
works similar to @code{let*}. Based on @coderef{ffi:with-foreign-string}.
@end defmac
@node Functions and Libraries
@ -1057,7 +1059,7 @@ works similar to @code{let*}. Based on @code{with-foreign-string}.
@subsubheading Reference
@lspindex ffi:def-function
@lspdef ffi:def-function
@defmac ffi:def-function name args &key module (returning :void) (call :cdecl)
@table @var
@item name
@ -1068,16 +1070,16 @@ 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.
@item args
A list of argument declarations. If @code{NIL}, indicates that the function
A list of argument declarations. If @code{nil}, indicates that the function
does not take any arguments.
@item module
Either a string specifying which module (or library) that the foreign
function resides, @code{:default} if no module needs to be loaded or
@code{NIL} to use SFFI.
@code{nil} to use SFFI.
@item call
Function calling convention. May be one of @code{:default}, @code{:cdecl},
@code{:sysv}, @code{:stdcall}, @code{:win64} and
@code{unix64}.
@code{:unix64}.
This argument is used only when we're using the dynamic function
interface. If ECL is built without the DFFI support, then it uses SFFI
@ -1086,10 +1088,10 @@ the @var{call} argument is ignored.
A declaration specifying the result type of the foreign function.
@code{:void} indicates that the function does not return any value.
@end table
@subsubheading Description
@paragraph Description
Declares a foreign function.
@subsubheading Examples
@exindex @code{ffi:def-function}
@paragraph Examples
@exindex @coderef{ffi:def-function}
@lisp
(ffi:def-function "gethostname"
((name (* :unsigned-char))
@ -1098,7 +1100,7 @@ Declares a foreign function.
@end lisp
@end defmac
@lspindex ffi:load-foreign-library
@lspdef ffi:load-foreign-library
@defmac ffi:load-foreign-library filename &key module supporting-libraries force-load system-library
@table @var
@item filename
@ -1114,30 +1116,30 @@ the foreign library.
previously loaded.
@item system-library
Denotes if the loaded library is a system library (accessible with the
correct linker flags). If @code{T}, then SFFI is used and the linking is
correct linker flags). If @code{t}, then SFFI is used and the linking is
performed after compilation of the module. Otherwise (default) both SFFI
and DFFI are used, but SFFI only during the compilation.
@item returns
A generalized boolean @emph{true} if the library was able to be loaded
successfully or if the library has been previously loaded, otherwise
@code{NIL}.
@code{nil}.
@end table
@subsubheading Description
@paragraph Description
Loads a foreign library. Ensures that a library is only loaded once
during a session.
@subsubheading Examples
@exindex @code{ffi:load-foreign-library}
@paragraph Examples
@exindex @coderef{ffi:load-foreign-library}
@lisp
(ffi:load-foreign-library #p"/usr/lib/libmagic.so.1")
;; => #<codeblock "/usr/lib/libmagic.so">
@end lisp
@subsubheading Side Effects
@paragraph Side Effects
Loads the foreign code into the Lisp system.
@subsubheading Affected by
@paragraph Affected by
Ability to load the file.
@end defmac
@lspindex ffi:find-foreign-library
@lspdef ffi:find-foreign-library
@defun ffi:find-foreign-library names directories &key drive-letters types
Finds a foreign library file
@table @var
@ -1151,17 +1153,17 @@ A string or list of strings containing the drive letters for the library
file.
@item types
A string or list of strings containing the file type of the library
file. Default is @code{NIL}. If @code{NIL}, will use a default type
file. Default is @code{nil}. If @code{nil}, will use a default type
based on the currently running implementation.
@item returns
A path containing the path to the @emph{first} file found, or
@code{NIL} if the library file was not found.
@code{nil} if the library file was not found.
@end table
@subsubheading Description
@paragraph Description
Finds a foreign library by searching through a number of possible
locations. Returns the path of the first found file.
@subsubheading Examples
@exindex @code{ffi:find-foreign-library}
@paragraph Examples
@exindex @coderef{ffi:find-foreign-library}
@lisp
(ffi:find-foreign-library '("libz" "libmagic")
'("/usr/local/lib/" "/usr/lib/")
@ -1184,15 +1186,15 @@ locations. Returns the path of the first found file.
@c One value? More?
@c @end table
@c @subsubheading Description
@c @paragraph Description
@c Description here
@c @subsubheading Examples
@c @paragraph Examples
@c @exindex @code{ffi:} sample run
@c @lisp
@c @end lisp
@c @subsubheading Side effects
@c @paragraph Side effects
@c foo bar
@c @end defmac

View file

@ -44,28 +44,29 @@ Beginning with version 9.2.1, ECL operates a tighter control of the resources it
The customizable limits are listed in @ref{tab:mem-limits}, but they need a careful description.
@lspindex ext:heap-size
@lspindex ext:c-stack
@lspindex ext:binding-stack
@lspindex ext:lisp-stack
@lspdef ext:heap-size
@lspdef ext:c-stack
@lspdef ext:binding-stack
@lspdef ext:frame-stack
@lspdef ext:lisp-stack
@itemize
@item
@code{ext:heap-size} limits the total amount of memory which is available for lisp objects. This is the memory used when you create conses, arrays, structures, etc.
@coderef{ext:heap-size} limits the total amount of memory which is available for lisp objects. This is the memory used when you create conses, arrays, structures, etc.
@item
@code{ext:c-stack} 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.
@coderef{ext:c-stack} 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.
@item
@code{ext:binding-stack} 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.
@coderef{ext:binding-stack} 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.
@item
@code{ext:frame-stack} controls the number of nested blocks, tagbodys 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.
@coderef{ext:frame-stack} controls the number of nested blocks, tagbodys 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.
@item
@code{ext:lisp-stack} controls the size of the interpreter stack. It only affects interpreted code.
@coderef{ext:lisp-stack} controls the size of the interpreter stack. It only affects interpreted code.
@end itemize
If you look at @ref{tab:mem-limits}, 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 @file{~/.eclrc} initialization file, or using the command line options from the table.
@node Memory conditions
@subsection Memory conditions
When ECL surpasses or approaches the memory limits it will signal a Common Lisp condition. There are two types of conditions, @code{ext:stack-overflow} and @code{ext:storage-exhausted}, for stack and heap overflows, respectively. Both errors are correctable, as the following session shows:
When ECL surpasses or approaches the memory limits it will signal a Common Lisp condition. There are two types of conditions, @coderef{ext:stack-overflow} and @coderef{ext:storage-exhausted}, for stack and heap overflows, respectively. Both errors are correctable, as the following session shows:
@lisp
> (defun foo (x) (foo x))
@ -101,6 +102,6 @@ If the finalizer is invoked and it makes the object reachable, for instance, by
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.
@end itemize
The implementation is based on two functions, @code{ext:set-finalizer} and @code{ext:get-finalizer}, which allow setting and querying the finalizer functions for certain objects.
The implementation is based on two functions, @coderef{ext:set-finalizer} and @coderef{ext:get-finalizer}, which allow setting and querying the finalizer functions for certain objects.
@include extensions/memory_ref.txi

View file

@ -3,16 +3,16 @@
@subsubheading Reference
@lspindex ext:stack-overflow
@lspdef ext:stack-overflow
@deftp Condition ext:stack-overflow
Stack overflow condition
@subsubheading Class Precedence List
@code{ext:stack-overflow, storage-condition, serious-condition, condition, t}
@paragraph Class Precedence List
@coderef{ext:stack-overflow}, @code{storage-condition}, @code{serious-condition}, @code{condition}, @code{t}
@subsubheading Methods
@lspindex ext:stack-overflow-size
@paragraph Methods
@lspdef ext:stack-overflow-size
@defun ext:stack-overflow-size condition
@table @var
@item returns
@ -20,30 +20,30 @@ A non-negative integer.
@end table
@end defun
@lspindex ext:stack-overflow-type
@lspdef ext:stack-overflow-type
@defun ext:stack-overflow-type condition
@table @var
@item returns
A symbol from @ref{tab:mem-limits}, except @code{ext:heap-size}.
A symbol from @ref{tab:mem-limits}, except @coderef{ext:heap-size}.
@end table
@end defun
@subsubheading Description
@paragraph Description
This condition is signaled when one of the stack limits in @ref{tab:mem-limits} are violated or dangerously approached. It can be handled by resetting the limits and continuing, or jumping to an outer control point.
@end deftp
@lspindex ext:storage-exhausted
@lspdef ext:storage-exhausted
@deftp Condition ext:storage-exhausted
Memory overflow condition
@subsubheading Class Precedence List
@code{ext:storage-exhausted, storage-condition, serious-condition, condition, t}
@paragraph Class Precedence List
@coderef{ext:storage-exhausted}, @code{storage-condition}, @code{serious-condition}, @code{condition}, @code{t}
@subsubheading Description
This condition is signaled when ECL exhausts the @code{ext:heap-size} limit from @ref{tab:mem-limits}. In handling this condition ECL follows this logic:
@paragraph Description
This condition is signaled when ECL exhausts the @coderef{ext:heap-size} limit from @ref{tab:mem-limits}. In handling this condition ECL follows this logic:
@itemize
@item
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.
@ -55,43 +55,43 @@ This condition is signaled when ECL exhausts the @code{ext:heap-size} limit from
@end deftp
@lspindex ext:get-finalizer
@lspdef ext:get-finalizer
@defun ext:get-finalizer object
@table @var
@item object
Any lisp object.
@end table
@subsubheading Description
This function returns the finalizer associated to an object, or @code{NIL}.
@paragraph Description
This function returns the finalizer associated to an object, or @code{nil}.
@end defun
@lspindex ext:get-limit
@lspdef ext:get-limit
@defun ext:get-limit concept
@table @var
@item concept
A symbol.
@end table
@subsubheading Description
@paragraph Description
Queries the different memory and stack limits that condition ECL's behavior. The value to be queried is denoted by the symbol @var{concept}, which should be one from the list: @ref{tab:mem-limits}
@end defun
@lspindex ext:set-finalizer
@lspdef ext:set-finalizer
@defun ext:set-finalizer object function
Associate a finalizer to an object.
@table @var
@item object
Any lisp object.
@item function
A function or closure that takes one argument or @code{NIL}.
A function or closure that takes one argument or @code{nil}.
@end table
@subsubheading Description
If @var{function} is @code{NIL}, no finalizer is associated to the object. Otherwise @var{function} must be a function or a closure of one argument, which will be invoked before the object is destroyed.
@paragraph Description
If @var{function} is @code{nil}, no finalizer is associated to the object. Otherwise @var{function} must be a function or a closure of one argument, which will be invoked before the object is destroyed.
@subsubheading Example
@paragraph Example
Close a file associated to an object.
@lisp
@ -117,7 +117,7 @@ Close a file associated to an object.
@end defun
@lspindex ext:set-limit
@lspdef ext:set-limit
@defun ext:set-limit concept value
Set a memory or stack limit.
@table @var

View file

@ -9,37 +9,37 @@ similar to @code{setf}.
@subsection Atomic operations dictionary
@subsubheading C Reference
@cppindex ecl_compare_and_swap
@cppdef ecl_compare_and_swap
@deftypefun cl_object ecl_compare_and_swap (cl_object *slot, cl_object old, cl_object new)
Perform an atomic compare and swap operation on @var{slot} and return
the previous value stored in @var{slot}. If the return value is equal
to @var{old} (comparison by @code{==}), the operation has succeeded.
This is a inline-only function defined in ``ecl/ecl_atomics.h''.
This is a inline-only function defined in "ecl/ecl_atomics.h".
@end deftypefun
@cppindex ecl_atomic_incf
@cppdef ecl_atomic_incf
@deftypefun cl_object ecl_atomic_incf (cl_object *slot, cl_object increment)
@end deftypefun
@cppindex ecl_atomic_incf_by_fixnum
@cppdef ecl_atomic_incf_by_fixnum
@deftypefun cl_object ecl_atomic_incf_by_fixnum (cl_object *slot, cl_fixnum increment)
Atomically increment @var{slot} by the given increment and return the
previous value stored in @var{slot}. The consequences are undefined if
the value of @var{slot} is not of type @code{fixnum}.
@code{ecl_atomic_incf} signals an error if @var{increment} is not of
@coderef{ecl_atomic_incf} signals an error if @var{increment} is not of
type @code{fixnum}. This is a inline-only function defined in
``ecl/ecl_atomics.h''.
"ecl/ecl_atomics.h".
@end deftypefun
@cppindex ecl_atomic_index_incf
@cppdef ecl_atomic_index_incf
@deftypefun cl_index ecl_atomic_index_incf (cl_index *slot);
Atomically increment @var{slot} by 1 and return the new value stored
in @var{slot}.
@end deftypefun
@cppindex ecl_atomic_get
@cppdef ecl_atomic_get
@deftypefun cl_object ecl_atomic_get (cl_object *slot)
Perform a volatile load of the object in @var{slot} and then
@ -47,26 +47,25 @@ atomically set @var{slot} to @code{ECL_NIL}. Returns the value
previously stored in @var{slot}.
@end deftypefun
@cppindex ecl_atomic_push
@cppdef ecl_atomic_push
@deftypefun void ecl_atomic_push (cl_object *slot, cl_object o)
@end deftypefun
@cppindex ecl_atomic_pop
@cppdef ecl_atomic_pop
@deftypefun cl_object ecl_atomic_pop (cl_object *slot)
Like push/pop but atomic.
@end deftypefun
@subsubheading Lisp Reference
@lspindex mp:atomic-incf
@lspdef mp:atomic-incf
@lspdef mp:atomic-decf
@defmac mp:atomic-incf place &optional (increment 1)
@end defmac
@lspindex mp:atomic-decf
@defmac mp:atomic-decf place &optional (increment 1)
@defmacx mp:atomic-decf place &optional (increment 1)
Atomically increments/decrements the fixnum stored in @var{place} by
the given @var{increment} and returns the value of @var{place} before
the increment. Incrementing and decrementing is done using modular
arithmetic, so that @code{mp:atomic-incf} of a place whose value is
arithmetic, so that @coderef{mp:atomic-incf} of a place whose value is
@code{most-positive-fixnum} by 1 results in
@code{most-negative-fixnum} stored in place.
@ -85,7 +84,7 @@ The consequences are undefined if the value of @var{place} is not of
type @code{fixnum}.
@end defmac
@lspindex mp:compare-and-swap
@lspdef mp:compare-and-swap
@defmac mp:compare-and-swap place old new
Atomically stores @var{new} in @var{place} if @var{old} is @code{eq}
@ -102,8 +101,8 @@ Currently, the following places are supported:
accessor@footnote{The creation of atomic structure slot accessors can be
deactivated by supplying a @code{(:atomic-accessors nil)} option to
@code{defstruct}.} or any other place for which a compare-and-swap
expansion was defined by @code{mp:defcas} or
@code{mp:define-cas-expander}.
expansion was defined by @coderef{mp:defcas} or
@coderef{mp:define-cas-expander}.
For @code{slot-value}, @code{slot-unbound} is called if the slot is
unbound unless @var{old} is @code{eq} to @code{si:unbound}, in which
@ -112,7 +111,7 @@ Additionally, the object should have no applicable methods defined for
@code{slot-value-using-class} or @code{(setf slot-value-using-class)}.
@end defmac
@lspindex mp:atomic-update
@lspdef mp:atomic-update
@defmac mp:atomic-update place update-fn &rest arguments
Atomically updates the CAS-able @var{place} to the value returned by
@ -147,17 +146,16 @@ the result would be unpredictable.
@end lisp
@end defmac
@lspindex mp:atomic-push
@lspdef mp:atomic-push
@lspdef mp:atomic-pop
@defmac mp:atomic-push obj place
@end defmac
@lspindex mp:atomic-pop
@defmac mp:atomic-pop place
@defmacx mp:atomic-pop place
Like @code{push}/@code{pop}, but atomic. @var{place} must be CAS-able
and may be read multiple times before the update succeeds.
@end defmac
@lspindex mp:define-cas-expander
@lspdef mp:define-cas-expander
@defmac mp:define-cas-expander accessor lambda-list &body body
Define a compare-and-swap expander similar to
@ -165,7 +163,7 @@ Define a compare-and-swap expander similar to
generalized-variables @code{(accessor ...)}. When a form
@code{(mp:compare-and-swap (accessor arg1 ... argn) old new)} is
evaluated, the forms given in the body of
@code{mp:define-cas-expander} are evaluated in order with the
@coderef{mp:define-cas-expander} are evaluated in order with the
parameters in @code{lambda-list} bound to @code{arg1 ... argn}. The
body must return six values
@lisp
@ -188,35 +186,49 @@ variables, unlike in @code{define-setf-expander}). The whole
Note that it is up to the user of this macro to ensure atomicity for
the resulting compare-and-swap expansions.
@exindex CAS expansion definition
Example:
@exindex Define a compare-and-swap expansion
@paragraph Example
CAS expansion for @code{mp:process-name}. A process is defined as
follows in C:
@example
@verbatim
struct ecl_process {
_ECL_HDR;
cl_object name;
cl_object function;
...
};
@end verbatim
@end example
Hence we can define a CAS expander as (omitting type checks):
@coderef{mp:define-cas-expander} can be used to define a more
convienient compare-and-swap expansion for a class slot. Consider the
following class:
@lisp
(mp:define-cas-expander mp:process-name (x)
(let ((old (gensym)) (new (gensym)))
(defclass food ()
((name :initarg :name)
(deliciousness :initform 5 :type '(integer 0 10)
:accessor food-deliciousness)))
(defvar *spätzle* (make-instance 'food :name "Spätzle"))
@end lisp
We can't just use @coderef{mp:compare-and-swap} on
@code{*spätzle*}:
@lisp
> (mp:compare-and-swap (food-deliciousness *x*) 5 10)
Condition of type: SIMPLE-ERROR
Cannot get the compare-and-swap expansion of (FOOD-DELICIOUSNESS *X*).
@end lisp
We can use @code{symbol-value}, but let's define a more convenient
compare-and-swap expander:
@lisp
(mp:define-cas-expander food-deliciousness (food)
(let ((old (gensym))
(new (gensym)))
(values nil nil old new
`(ffi:c-inline (,x ,old ,new) (:object :object :object) :object
"ecl_compare_and_swap(&(#0)->process.name,#1,#2)"
:one-liner t)
`(mp:process-name ,x))))
`(progn (check-type ,new (integer 0 10))
(mp:compare-and-swap (slot-value ,food 'deliciousness)
,old ,new))
`(food-deliciousness ,food))))
@end lisp
Now finally, we can safely store our rating:
@lisp
> (mp:compare-and-swap (food-deliciousness *spätzle*) 5 10)
5
@end lisp
@end defmac
@lspindex mp:defcas
@lspdef mp:defcas
@defmac mp:defcas accessor cas-fun &optional documentation
Define a compare-and-swap expansion similar to the short form
@ -229,16 +241,16 @@ Note that it is up to the user of this macro to ensure atomicity for
the resulting compare-and-swap expansions.
@end defmac
@lspindex mp:remcas
@lspdef mp:remcas
@defun mp:remcas symbol
Remove a compare-and-swap expansion. It is an equivalent of
@code{fmakunbound (setf symbol)} for cas expansions.
@end defun
@lspindex mp:get-cas-expansion
@lspdef mp:get-cas-expansion
@defun mp:get-cas-expansion place &optional environment
Returns the compare-and-swap expansion forms and variables as
defined in @code{mp:define-cas-expander} for @var{place} as six values.
Returns the compare-and-swap expansion forms and variables as defined in
@coderef{mp:define-cas-expander} for @var{place} as six values.
@end defun

View file

@ -8,8 +8,8 @@ true (e.g new client connects to the server).
@subsection Condition variables dictionary
@cppindex mp_make_condition_variable
@lspindex mp:make-condition-variable
@cppdef mp_make_condition_variable
@lspdef mp:make-condition-variable
@deftypefun cl_object mp_make_condition_variable ()
@end deftypefun
@ -19,53 +19,53 @@ Creates a condition variable.
@end defun
@cppindex mp_condition_variable_wait
@lspindex mp:condition-variable-wait
@cppdef mp_condition_variable_wait
@lspdef mp:condition-variable-wait
@deftypefun cl_object mp_condition_variable_wait (cl_object cv, cl_object lock)
@end deftypefun
@defun mp:condition-variable-wait cv lock
Release @code{lock} and suspend thread until condition
@code{mp:condition-variable-signal} is called on @code{cv}. When thread
resumes re-aquire @code{lock}.
Release @var{lock} and suspend thread until condition
@coderef{mp:condition-variable-signal} is called on @var{cv}. When thread
resumes re-aquire @var{lock}.
@end defun
@cppindex mp_condition_variable_timedwait
@lspindex mp:condition-variable-timedwait
@cppdef mp_condition_variable_timedwait
@lspdef mp:condition-variable-timedwait
@deftypefun cl_object mp_condition_variable_timedwait (cl_object cv, cl_object lock, cl_object seconds)
@end deftypefun
@defun mp:condition-variable-timedwait cv lock seconds
@code{mp:condition-variable-wait} which timeouts after @code{seconds}
@coderef{mp:condition-variable-wait} which timeouts after @var{seconds}
seconds.
@end defun
@cppindex mp_condition_variable_signal
@lspindex mp:condition-variable-signal
@cppdef mp_condition_variable_signal
@lspdef mp:condition-variable-signal
@deftypefun cl_object mp_condition_variable_signal (cl_object cv)
@end deftypefun
@defun mp:condition-variable-signal cv
Signal @code{cv} (wakes up only one waiter). After signal, signaling
Signal @var{cv} (wakes up only one waiter). After signal, signaling
thread keeps lock, waking thread goes on the queue waiting for the lock.
See @code{mp:condition-variable-wait}.
See @coderef{mp:condition-variable-wait}.
@end defun
@cppindex mp_condition_variable-broadcast
@lspindex mp:condition-variable-broadcast
@cppdef mp_condition_variable-broadcast
@lspdef mp:condition-variable-broadcast
@deftypefun cl_object mp_condition_variable_broadcast (cl_object cv)
@end deftypefun
@defun mp:condition-variable-broadcast cv
Signal @code{cv} (wakes up all waiters).
Signal @var{cv} (wakes up all waiters).
See @code{mp:condition-variable-wait}.
See @coderef{mp:condition-variable-wait}.
@end defun

View file

@ -10,117 +10,116 @@ can't).
@subsection Locks dictionary
@cppindex ecl_make_lock
@cppdef ecl_make_lock
@deftypefun cl_object ecl_make_lock (cl_object name, bool recursive)
C/C++ equivalent of @code{mp:make-lock} without @code{key} arguments.
C/C++ equivalent of @coderef{mp:make-lock} without @var{key} arguments.
See @code{mp:make-lock}.
See @coderef{mp:make-lock}.
@end deftypefun
@lspindex mp:make-lock
@lspdef mp:make-lock
@defun mp:make-lock &key name (recursive nil)
Creates a lock @code{name}. If @code{recursive} isn't @code{nil}, then
the created lock is recursive.
Creates a lock named @var{name}. If @var{recursive} is true, a recursive
lock is created that can be locked multiple times by the same thread.
@end defun
@cppindex mp_recursive_lock_p
@lspindex mp:recursive-lock-p
@cppdef mp_recursive_lock_p
@lspdef mp:recursive-lock-p
@deftypefun cl_object mp_recursive_lock_p (cl_object lock)
@end deftypefun
@defun mp:recursive-lock-p lock
Predicate verifying if @code{lock} is recursive.
Predicate verifying if @var{lock} is recursive.
@end defun
@cppindex mp_holding_lock_p
@lspindex mp:holding-lock-p
@cppdef mp_holding_lock_p
@lspdef mp:holding-lock-p
@deftypefun cl_object mp_holding_lock_p (cl_object lock)
@end deftypefun
@defun mp:holding-lock-p lock
Predicate verifying if the current thread holds @code{lock}.
Predicate verifying if the current thread holds @var{lock}.
@end defun
@cppindex mp_lock_name
@lspindex mp:lock-name
@cppdef mp_lock_name
@lspdef mp:lock-name
@deftypefun cl_object mp_lock_name (cl_object lock)
@end deftypefun
@defun mp:lock_name lock
Returns @code{lock} name.
Returns the name of @var{lock}.
@end defun
@lspindex mp_lock_owner
@lspindex mp:lock-owner
@lspdef mp_lock_owner
@lspdef mp:lock-owner
@deftypefun cl_object mp_lock_owner (cl_object lock)
@end deftypefun
@defun mp:lock_owner lock
Returns process owning @code{lock} (or @code{nil} if it is free). For
testing whether the current thread is holding a lock see
@code{holding-lock-p}.
@defun mp:lock-owner lock
Returns the process owning @var{lock}. For testing whether the current
thread is holding a lock see @coderef{mp:holding-lock-p}.
@end defun
@cppindex mp_lock_count
@lspindex mp:lock-count
@cppdef mp_lock_count
@lspdef mp:lock-count
@deftypefun cl_object mp_lock_count (cl_object lock)
@end deftypefun
@defun mp:lock-count lock
Returns number of processes waiting for @code{lock}.
Returns number of processes waiting for @var{lock}.
@end defun
@cppindex mp_get_lock_wait
@cppindex mp_get_lock_nowait
@lspindex mp:get-lock
@cppdef mp_get_lock_wait
@cppdef mp_get_lock_nowait
@lspdef mp:get-lock
@deftypefun cl_object mp_get_lock_wait (cl_object lock)
Grabs a lock (blocking if @code{lock} is already taken). Returns
Grabs a lock (blocking if @var{lock} is already taken). Returns
@code{ECL_T}.
@end deftypefun
@deftypefun cl_object mp_get_lock_nowait
Grabs a lock if free (non-blocking). If @code{lock} is already taken
Grabs a lock if free (non-blocking). If @var{lock} is already taken
returns @code{ECL_NIL}, otherwise @code{ECL_T}.
@end deftypefun
@defun mp:get-lock lock &optional (wait t)
Tries to acquire a lock. @code{wait} indicates whenever function should
block or give up if @code{lock} is already taken. If @code{wait} is
@code{nil} and @code{lock} can't be acquired returns
Tries to acquire a lock. @var{wait} indicates whether function should
block or give up if @var{lock} is already taken. If @var{wait} is
@code{nil} and @var{lock} can't be acquired returns
@code{nil}. Succesful operation returns @code{t}.
@end defun
@cppindex mp_giveup_lock
@lspindex mp:giveup-lock
@cppdef mp_giveup_lock
@lspdef mp:giveup-lock
@deftypefun cl_object mp_giveup_lock (cl_object lock)
@end deftypefun
@defun mp:giveup_lock lock
Releases @code{lock}.
@defun mp:giveup-lock lock
Releases @var{lock}.
@end defun
@lspindex mp:with-lock
@lspdef mp:with-lock
@defmac mp:with-lock (lock-form) &body body
Acquire lock for the dynamic scope of @code{body}, which is executed
Acquire lock for the dynamic scope of @var{body}, which is executed
with the lock held by current thread. Returns the values of body.
@c (lock-form &key wait-p timeout)

View file

@ -6,8 +6,8 @@ Process is a primitive representing native thread.
@node Processes dictionary
@subsection Processes dictionary
@cppindex mp_all_processes
@lspindex mp:all-processes
@cppdef mp_all_processes
@lspdef mp:all-processes
@deftypefun cl_object mp_all_processes ()
@end deftypefun
@ -22,8 +22,8 @@ expired before this copy is returned.
@end defun
@cppindex mp_exit_process
@lspindex mp:exit-process
@cppdef mp_exit_process
@lspdef mp:exit-process
@deftypefun cl_object mp_exit_process () ecl_attr_noreturn
@end deftypefun
@ -32,26 +32,26 @@ expired before this copy is returned.
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 @code{ext:quit} with exit code 0.
invoking @coderef{ext:quit} with exit code 0.
@end defun
@cppindex mp_interrupt_process
@lspindex mp:interrupt-process
@cppdef mp_interrupt_process
@lspdef mp:interrupt-process
@deftypefun cl_object mp_interrupt_process (cl_object process, cl_object function)
@end deftypefun
@defun mp:interrupt-process process function
Interrupt a task. This @code{function} sends a signal to a running
@code{process}. When the task is free to process that signal, it will
Interrupt a task. This function sends a signal to a running
@var{process}. When the task is free to process that signal, it will
stop whatever it is doing and execute the given function.
@strong{WARNING:} Use with care! Interrupts can happen anywhere,
except in code regions explicitely protected with
@code{mp:without-interrupts}. This can lead to dangerous situations
@coderef{mp:without-interrupts}. This can lead to dangerous situations
when interrupting functions which are not thread safe. In particular,
one has to consider:
@itemize
@ -62,7 +62,7 @@ one has to consider:
@exindex Process interruption
Example:
Kill a task that is doing nothing (See @code{mp:process-kill}).
Kill a task that is doing nothing (See @coderef{mp:process-kill}).
@lisp
(flet ((task-to-be-killed ()
@ -76,8 +76,8 @@ Kill a task that is doing nothing (See @code{mp:process-kill}).
@end defun
@cppindex mp_make_process
@lspindex mp:make-process
@cppdef mp_make_process
@lspdef mp:make-process
@deftypefun cl_object mp_make_process (cl_narg narg, ...)
@end deftypefun
@ -85,33 +85,33 @@ Kill a task that is doing nothing (See @code{mp:process-kill}).
@defun mp:make-process &key name initial-bindings
Create a new thread. This function creates a separate task with a name
set to @code{name} and no function to run. See also
@code{mp:process-run-function}. Returns newly created process.
set to @var{name} and no function to run. See also
@coderef{mp:process-run-function}. Returns newly created process.
If @code{initial-bindings} is false, the new process inherits local
If @var{initial-bindings} is false, the new process inherits local
bindings to special variables (i.e. binding a special variable with
@code{let} or @code{let*}) from the current thread, otherwise the new
thread possesses no local bindings.
@end defun
@cppindex mp_process_active_p
@lspindex mp:process-active-p
@cppdef mp_process_active_p
@lspdef mp:process-active-p
@deftypefun cl_object mp_process_active_p (cl_object process)
@end deftypefun
@defun mp:process-active-p process
Returns @code{t} when @code{process} is active, @code{nil}
otherwise. Signals an error if @code{process} doesn't designate a valid
Returns @code{t} when @var{process} is active, @code{nil}
otherwise. Signals an error if @var{process} doesn't designate a valid
process.
@end defun
@cppindex mp_process_enable
@lspindex mp:process-enable
@cppdef mp_process_enable
@lspdef mp:process-enable
@deftypefun cl_object mp_process_enable (cl_object process)
@end deftypefun
@ -119,13 +119,13 @@ process.
@defun mp:process-enable process
The argument to this function should be a process created by
@code{mp:make-process}, which has a function associated as per
@code{mp:process-preset} but which is not yet running. After invoking
@coderef{mp:make-process}, which has a function associated as per
@coderef{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. Returns @code{process} if the thread
function will be executed. Returns @var{process} if the thread
creation was successful and @code{nil} otherwise.
@exindex Possible implementation of @code{mp:process-run-function}:
@exindex Possible implementation of @coderef{mp:process-run-function}:
@lisp
(defun process-run-function (process-name process-function &rest args)
@ -136,8 +136,8 @@ creation was successful and @code{nil} otherwise.
@end defun
@cppindex mp_process_yield
@lspindex mp:process-yield
@cppdef mp_process_yield
@lspdef mp:process-yield
@deftypefun cl_object mp_process_yield ()
@end deftypefun
@ -147,20 +147,20 @@ Yield the processor to other threads.
@end defun
@cppindex mp_process-join
@lspindex mp:process-join
@cppdef mp_process-join
@lspdef mp:process-join
@deftypefun cl_object mp_process_join (cl_object process)
@end deftypefun
@defun mp:process-join process
Suspend current thread until @code{process} exits. Return the result
values of the @code{process} function.
Suspend current thread until @var{process} exits. Return the result
values of the @var{process} function.
@end defun
@cppindex mp_process_kill
@lspindex mp:process-kill
@cppdef mp_process_kill
@lspdef mp:process-kill
@deftypefun cl_object mp_process_kill (cl_object process)
@end deftypefun
@ -184,15 +184,15 @@ Kill a task that is doing nothing
@end defun
@cppindex mp_process_suspend
@lspindex mp:process-suspend
@cppdef mp_process_suspend
@lspdef mp:process-suspend
@deftypefun cl_object mp_process_suspend (cl_object process)
@end deftypefun
@defun mp:process-suspend process
Suspend a running @code{process}. May be resumed with
@code{mp:process-resume}.
Suspend a running @var{process}. May be resumed with
@coderef{mp:process-resume}.
@exindex Suspend and resume process
Example:
@ -218,55 +218,55 @@ Example:
@end defun
@cppindex mp_process_resume
@lspindex mp:process-resume
@cppdef mp_process_resume
@lspdef mp:process-resume
@deftypefun cl_object mp_process_resume (cl_object process)
@end deftypefun
@defun mp:process-resume process
Resumes a suspended @code{process}. See example in
@code{mp:process-suspend}.
Resumes a suspended @var{process}. See example in
@coderef{mp:process-suspend}.
@end defun
@cppindex mp_process_name
@lspindex mp:process-name
@cppdef mp_process_name
@lspdef mp:process-name
@deftypefun cl_object mp_process_name (cl_object process)
@end deftypefun
@defun mp:process-name process
Returns the name of a @code{process} (if any).
Returns the name of a @var{process} (if any).
@end defun
@cppindex mp_process_preset
@lspindex mp:process-preset
@cppdef mp_process_preset
@lspdef mp:process-preset
@deftypefun cl_object mp_process_preset (cl_narg narg, cl_object process, cl_object function, ...)
@end deftypefun
@defun mp:process-preset process function &rest function-args
Associates a @code{function} to call with the arguments
@code{function-args}, with a stopped @code{process}. The function will
Associates a @var{function} to call with the arguments
@var{function-args}, with a stopped @var{process}. The function will
be the entry point when the task is enabled in the future.
See @code{mp:enable-process} and @code{mp:process-run-function}.
See @coderef{mp:process-enable} and @coderef{mp:process-run-function}.
@end defun
@cppindex mp_process_run_function
@lspindex mp:process-run-function
@cppdef mp_process_run_function
@lspdef mp:process-run-function
@deftypefun cl_object mp_process_run_function (cl_narg narg, cl_object name, cl_object function, ...)
@end deftypefun
@defun mp:process-run-function name function &rest function-args
Create a new process using @code{mp:make-process}, associate a function
to it and start it using @code{mp:process-preset}.
Create a new process using @coderef{mp:make-process}, associate a function
to it and start it using @coderef{mp:process-preset}.
@exindex mp:process-run-function usage
Example:
@ -282,8 +282,8 @@ Example:
@end defun
@cppindex mp_current_process
@lspindex mp:*current-process*
@cppdef mp_current_process
@lspdef mp:*current-process*
@deftypefun cl_object mp_current_process ()
@end deftypefun
@ -293,8 +293,8 @@ Returns/holds the current process of a caller.
@end defvr
@cppindex mp_block_signals
@lspindex mp:block-signals
@cppdef mp_block_signals
@lspdef mp:block-signals
@deftypefun cl_object mp_block_signals ()
@end deftypefun
@ -302,88 +302,89 @@ Returns/holds the current process of a caller.
@defun mp:block-signals
Blocks process for interrupts and returns the previous sigmask.
See @code{mp:interrupt-process}.
See @coderef{mp:interrupt-process}.
@end defun
@cppindex mp_restore_signals
@lspindex mp:restore-signals
@cppdef mp_restore_signals
@lspdef mp:restore-signals
@deftypefun cl_object mp_restore_signals (cl_object sigmask)
@end deftypefun
@defun mp:restore-signals sigmask
Enables the interrupts from @code{sigmask}.
Enables the interrupts from @var{sigmask}.
See @code{mp:interrupt-process}.
See @coderef{mp:interrupt-process}.
@end defun
@lspindex mp:without-interrupts
@lspindex allow-with-interrupts
@lspindex with-local-interrupts
@lspindex with-restored-interrupts
@lspdef mp:without-interrupts
@lspdef mp:allow-with-interrupts
@lspdef mp:with-local-interrupts
@lspdef mp:with-restored-interrupts
@defmac mp:without-interrupts &body body
Executes @code{body} with all deferrable interrupts disabled. Deferrable
interrupts arriving during execution of the @code{body} take effect
after @code{body} has been executed.
Executes @var{body} with all deferrable interrupts disabled. Deferrable
interrupts arriving during execution of the @var{body} take effect
after @var{body} has been executed.
Deferrable interrupts include most blockable POSIX signals, and
@code{mp:interrupt-process}. Does not interfere with garbage collection,
and unlike in many traditional Lisps using userspace threads, in ECL
@code{mp:without-interrupts} does not inhibit scheduling of other
threads.
@coderef{mp:interrupt-process}. Does not interfere with garbage
collection, and unlike in many traditional Lisps using userspace
threads, in ECL @coderef{mp:without-interrupts} does not inhibit
scheduling of other threads.
Binds @code{allow-with-interrupts}, @code{with-local-interrupts} and
@code{with-restored-interrupts} as a local macros.
Binds @coderef{mp:allow-with-interrupts},
@coderef{mp:with-local-interrupts} and
@coderef{mp:with-restored-interrupts} as a local macros.
@code{with-restored-interrupts} executes the body with interrupts enabled if
and only if the @code{without-interrupts} was in an environment in which
interrupts were allowed.
@coderef{mp:with-restored-interrupts} executes the body with interrupts
enabled if and only if the @coderef{mp:without-interrupts} was in an
environment in which interrupts were allowed.
@code{allow-with-interrupts} allows the @code{with-interrupts} to take
effect during the dynamic scope of its body, unless there is an outer
@code{without-interrupts} without a corresponding
@code{allow-with-interrupts}.
@coderef{mp:allow-with-interrupts} allows the
@coderef{mp:with-interrupts} to take effect during the dynamic scope of
its body, unless there is an outer @coderef{mp:without-interrupts}
without a corresponding @coderef{mp:allow-with-interrupts}.
@code{with-local-interrupts} executes its body with interrupts enabled
provided that there is an @code{allow-with-interrupts} for every
@code{without-interrupts} surrounding the current
one. @code{with-local-interrupts} is equivalent to:
@coderef{mp:with-local-interrupts} executes its body with interrupts
enabled provided that there is an @coderef{mp:allow-with-interrupts} for
every @coderef{mp:without-interrupts} surrounding the current one.
@coderef{mp:with-local-interrupts} is equivalent to:
@lisp
(allow-with-interrupts (with-interrupts ...))
(mp:allow-with-interrupts (mp:with-interrupts ...))
@end lisp
Care must be taken not to let either @code{allow-with-interrupts} or
@code{with-local-interrupts} appear in a function that escapes from
inside the @code{without-interrupts} in:
Care must be taken not to let either @coderef{mp:allow-with-interrupts}
or @coderef{mp:with-local-interrupts} appear in a function that escapes
from inside the @coderef{mp:without-interrupts} in:
@lisp
(without-interrupts
(mp: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 ...)))
(lambda () (mp:allow-with-interrupts ...)))
(without-interrupts
(mp: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 ...)))
(lambda () (mp:with-local-interrupts ...)))
@end lisp
@end defmac
@lspindex mp:with-interrupts
@lspdef mp:with-interrupts
@defmac mp:with-interrupts &body body
Executes @code{body} with deferrable interrupts conditionally
Executes @var{body} with deferrable interrupts conditionally
enabled. If there are pending interrupts they take effect prior to
executing @code{body}.
executing @var{body}.
As interrupts are normally allowed @code{with-interrupts} only makes
sense if there is an outer @code{without-interrupts} with a
corresponding @code{allow-with-interrupts}: interrupts are not enabled
if any outer @code{without-interrupts} is not accompanied by
@code{allow-with-interrupts}.
As interrupts are normally allowed @coderef{mp:with-interrupts} only
makes sense if there is an outer @coderef{mp:without-interrupts} with a
corresponding @coderef{mp:allow-with-interrupts}: interrupts are not
enabled if any outer @coderef{mp:without-interrupts} is not accompanied
by @coderef{mp:allow-with-interrupts}.
@end defmac

View file

@ -17,102 +17,100 @@ Readers-writers locks are an optional feature, which is available if
@subsection Read-Write locks dictionary
@cppindex ecl_make_rwlock
@cppdef ecl_make_rwlock
@deftypefun cl_object ecl_make_rwlock (cl_object name)
C/C++ equivalent of @code{mp:make-rwlock} without @code{key} arguments.
C/C++ equivalent of @coderef{mp:make-rwlock} without @code{key} arguments.
See @code{mp:make-rwlock}.
See @coderef{mp:make-rwlock}.
@end deftypefun
@lspindex mp:make_rwlock
@lspdef mp:make-rwlock
@defun mp:make_rwlock &key name
Creates a rwlock with @code{name}.
@defun mp:make-rwlock &key name
Creates a rwlock named @var{name}.
@end defun
@cppindex mp_rwlock_name
@lspindex mp:rwlock-name
@cppdef mp_rwlock_name
@lspdef mp:rwlock-name
@deftypefun cl_object mp_rwlock_name (cl_object lock)
@end deftypefun
@defun mp:rwlock_name lock
Returns @code{lock} name.
@defun mp:rwlock-name lock
Returns the name of @var{lock}.
@end defun
@cppindex mp_get_rwlock_read_wait
@cppindex mp_get_rwlock_read_nowait
@lspindex mp:get-rwlock-read
@cppdef mp_get_rwlock_read_wait
@cppdef mp_get_rwlock_read_nowait
@lspdef mp:get-rwlock-read
@deftypefun cl_object mp_get_rwlock_read_wait (cl_object lock)
Acquires @code{lock} (blocks if @code{lock} is already taken with
@code{mp:get-rwlock-write}. Lock may be acquired by multiple
Acquires @var{lock} (blocks if @var{lock} is already taken with
@coderef{mp:get-rwlock-write}. Lock may be acquired by multiple
readers). Returns @code{ECL_T}.
@end deftypefun
@deftypefun cl_object mp_get_rwlock_read_nowait
Tries to acquire @code{lock}. If @code{lock} is already taken with
@code{mp:get-rwlock-write} returns @code{ECL_NIL}, otherwise
Tries to acquire @var{lock}. If @var{lock} is already taken with
@coderef{mp:get-rwlock-write} returns @code{ECL_NIL}, otherwise
@code{ECL_T}.
@end deftypefun
@defun mp:get-rwlock-read lock &optional (wait t)
Tries to acquire @code{lock}. @code{wait} indicates whenever function
should block or give up if @code{lock} is already taken with
@code{mp:get-rwlock-write}.
Tries to acquire @var{lock}. @var{wait} indicates whenever function
should block or give up if @var{lock} is already taken with
@coderef{mp:get-rwlock-write}.
@end defun
@cppindex mp_get_rwlock_write_wait
@cppindex mp_get_rwlock_write_nowait
@lspindex mp:get-rwlock-write
@cppdef mp_get_rwlock_write_wait
@cppdef mp_get_rwlock_write_nowait
@lspdef mp:get-rwlock-write
@deftypefun cl_object mp_get_rwlock_write_wait (cl_object lock)
Acquires @code{lock} (blocks if @code{lock} is already taken). Returns
Acquires @var{lock} (blocks if @var{lock} is already taken). Returns
@code{ECL_T}.
@end deftypefun
@deftypefun cl_object mp_get_rwlock_write_nowait
Tries to acquire @code{lock}. If @code{lock} is already taken returns
Tries to acquire @var{lock}. If @var{lock} is already taken returns
@code{ECL_NIL}, otherwise @code{ECL_T}.
@end deftypefun
@defun mp:get-rwlock-write lock &optional (wait t)
Tries to acquire @code{lock}. @code{wait} indicates whenever function
should block or give up if @code{lock} is already taken.
Tries to acquire @var{lock}. @var{wait} indicates whenever function
should block or give up if @var{lock} is already taken.
@end defun
@cppindex mp_giveup_rwlock_read
@cppindex mp_giveup_rwlock_write
@cppdef mp_giveup_rwlock_read
@cppdef mp_giveup_rwlock_write
@lspindex mp:giveup-rwlock-read
@lspindex mp:giveup-rwlock-write
@lspdef mp:giveup-rwlock-read
@lspdef mp:giveup-rwlock-write
@deftypefun cl_object mp_giveup_rwlock_read (cl_object lock)
@end deftypefun
@deftypefun cl_object mp_giveup_rwlock_write (cl_object lock)
@deftypefunx cl_object mp_giveup_rwlock_write (cl_object lock)
@end deftypefun
@defun mp:giveup-rwlock-read lock
@end defun
@defun mp:giveup-rwlock-write lock
Release @code{lock}.
@defunx mp:giveup-rwlock-write lock
Release @var{lock}.
@end defun
@lspindex mp:with-rwlock
@lspdef mp:with-rwlock
@defmac mp:with-rwlock (lock operation) &body body
Acquire rwlock for the dynamic scope of @code{body} for operation
@code{operation}, which is executed with the lock held by current
Acquire rwlock for the dynamic scope of @var{body} for operation
@var{operation}, which is executed with the lock held by current
thread. Returns the values of body.
Valid values of argument @code{operation} are @code{:read} or
Valid values of argument @var{operation} are @code{:read} or
@code{:write} (for reader and writer access accordingly).
@end defmac

View file

@ -9,59 +9,59 @@ of concurrent threads allowed to access it is limited.
@subsection Semaphores dictionary
@cppindex ecl_make_semaphore
@cppdef ecl_make_semaphore
@deftypefun cl_object ecl_make_semaphore (cl_object name, cl_fixnum count)
C/C++ equivalent of @code{mp:make-sempahore} without @code{key}
C/C++ equivalent of @coderef{mp:make-semaphore} without @code{key}
arguments.
See @code{mp:make-sempahore}.
See @coderef{mp:make-semaphore}.
@end deftypefun
@cppindex mp_make_semaphore
@lspindex mp:make-semaphore
@cppdef mp_make_semaphore
@lspdef mp:make-semaphore
@defun mp:make-semaphore &key name count
Creates a counting semaphore @code{name} with a resource count
@code{count}.
Creates a counting semaphore @var{name} with a resource count
@var{count}.
@end defun
@cppindex mp_semaphore_name
@lspindex mp:semaphore-name
@cppdef mp_semaphore_name
@lspdef mp:semaphore-name
@deftypefun cl_object mp_semaphore_name (cl_object semaphore)
@end deftypefun
@defun mp:semaphore-name semaphore
Returns @code{semaphore} name.
Returns the name of @var{semaphore}.
@end defun
@cppindex mp_semaphore_count
@lspindex mp:semaphore-count
@cppdef mp_semaphore_count
@lspdef mp:semaphore-count
@deftypefun cl_object mp_semaphore_count (cl_object semaphore)
@end deftypefun
@defun mp:semaphore-count semaphore
Returns @code{semaphore} count of resources.
Returns the resource count of @var{semaphore}.
@end defun
@cppindex mp_semaphore_wait_count
@lspindex mp:semaphore-wait-count
@cppdef mp_semaphore_wait_count
@lspdef mp:semaphore-wait-count
@deftypefun cl_object mp_semaphore_wait_count (cl_object semaphore)
@end deftypefun
@defun mp:semaphore-wait-count semaphore
Returns number of threads waiting on @code{semaphore}.
Returns the number of threads waiting on @var{semaphore}.
@end defun
@cppindex mp_wait_on_semaphore
@lspindex mp:wait-on-semaphore
@cppdef mp_wait_on_semaphore
@lspdef mp:wait-on-semaphore
@deftypefun cl_object mp_wait_on_semaphore (cl_object semaphore)
@end deftypefun
@ -72,8 +72,8 @@ resource count before semaphore was acquired.
@end defun
@cppindex mp_try_get_semaphore
@lspindex mp:try-get-semaphore
@cppdef mp_try_get_semaphore
@lspdef mp:try-get-semaphore
@deftypefun cl_object mp_try_get_semaphore (cl_object semaphore)
@end deftypefun
@ -85,12 +85,12 @@ was acquired.
@end defun
@lspindex mp_signal_semaphore
@lspindex mp:signal-semaphore
@lspdef mp_signal_semaphore
@lspdef mp:signal-semaphore
@deftypefun cl_object mp_signal_semaphore (cl_narg n, cl_object sem, ...);
@end deftypefun
@defun mp:signal-semaphore semaphore &optional (count 1)
Releases @code{count} units of a resource on @code{semaphore}.
Releases @var{count} units of a resource on @var{semaphore}.
@end defun

View file

@ -12,12 +12,15 @@
@cindex Command line processing
@node Command line arguments
@subsection Command line arguments
@lspdef ext:*help-message*
@deftypevar string ext:*help-message*
Command line help message. Initial value is ECL help message. This
variable contains the help message which is output when ECL is invoked
with the @code{--help}.
@end deftypevar
@lspdef ext:*lisp-init-file-list*
@deftypevar list-of-pathname-designators ext:*lisp-init-file-list*
ECL initialization files. Initial value is @code{'("~/.ecl"
"~/.eclrc")}. This variable contains the names of initialization files
@ -25,17 +28,19 @@ that are loaded by ECL or embedding programs. The loading of
initialization files happens automatically in ECL unless invoked with
the option @code{--norc}. Whether initialization files are loaded or
not is controlled by the command line options rules, as described in
@code{ext:process-command-args}.
@coderef{ext:process-command-args}.
@end deftypevar
@lspdef ext:+default-command-arg-rules+
@deftypevar list-of-lists ext:+default-command-arg-rules+
ECL command line options. 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 @code{ext:process-command-args}, and you can use it as a
argument to @coderef{ext:process-command-args}, and you can use it as a
starting point to extend ECL.
@end deftypevar
@lspdef ext:command-args
@defun ext:command-args
Original list of command line arguments. This function returns the
list of command line arguments passed to either ECL or the program it
@ -45,15 +50,16 @@ name of the program as it was invoked. You should not count on the
filename to be resolved.
@end defun
@lspdef ext:process-command-args
@defun ext:process-command-args &key args rules
@defvr argument args
A list of strings. Defaults to the output of @code{ext:command-args}.
@end defvr
@defvr argument rules
@table @var
@item args
A list of strings. Defaults to the output of @coderef{ext:command-args}.
@item rules
A list of lists. Defaults to the value of
@code{ext:+default-command-arg-rules+}.
@end defvr
@coderef{ext:+default-command-arg-rules+}.
@end table
This function processes the command line arguments passed to either
ECL or the program that embeds it. It uses the list of rules rules,
@ -61,51 +67,47 @@ which has the following syntax:
@code{(option-name nargs template [:stop | :noloadrc | :loadrc]*)}
@defvr opt option-name
@table @code
@item option-name
A string with the option prefix as typed by the user. For instance
@code{--help}, @code{-?}, @code{--compile}, etc.
@end defvr
@defvr opt nargs
@item nargs
A non-negative integer denoting the number of arguments taken by this
option.
@end defvr
@defvr opt template
@item template
A lisp form, not evaluated, where numbers from 0 to nargs will be
replaced by the corresponding option argument.
@end defvr
@defvr opt :stop
@item :stop
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 @code{--} command line
option to set @code{ext:*unprocessed-ecl-command-args*} to the list of
remaining arguments.
@end defvr
@defvr opt :noloadrc
@defvrx opt :loadrc
@item :noloadrc, :loadrc
Determine whether the lisp initialization files in
@code{ext:*lisp-init-file-list*} will be loaded before processing
@coderef{ext:*lisp-init-file-list*} will be loaded before processing
all forms.
@end defvr
@end table
@code{ext:process-command-args} works as follows. First of all, it
@coderef{ext:process-command-args} 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
succeeds.
A special name @code{*DEFAULT*}, matches any unknown command line
option. If there is no @code{*DEFAULT*} rule and no match is found, an
A special name @code{*default*}, matches any unknown command line
option. If there is no @code{*default*} rule and no match is found, an
error is signaled. For each rule that succeeds, the function
constructs a lisp statement using the template.
After all arguments have been processed,
@code{ext:process-command-args}, and there were no occurrences of
@coderef{ext:process-command-args}, and there were no occurrences of
@code{:noloadrc}, the first existing file listed in
@code{ext:*lisp-init-file-list*} will be loaded. Finally, the list of
@coderef{ext:*lisp-init-file-list*} will be loaded. Finally, the list of
lisp statements will be evaluated.
@end defun
@ -114,7 +116,7 @@ lisp statements will be evaluated.
The following piece of code implements the ls command using
lisp. Instructions for building this program are found under
@code{ecl/examples/cmdline/ls.lsp}.
@file{examples/cmdline/ls.lsp}.
@lisp
@verbatim
@ -147,25 +149,26 @@ ls [--help | -?] filename*
@subsection External processes
ECL provides several facilities for invoking and communicating with
@code{ext:external-process}. If one just wishes to execute some
program, without caring for its output, then probably
@code{ext:system} is the best function. In all other cases it is
preferable to use @code{ext:run-program}, which opens pipes to
communicate with the program and manipulate it while it runs on the
background.
external processes. If one just wishes to execute some program, without
caring for its output, then probably @coderef{ext:system} is the best
function. In all other cases it is preferable to use
@coderef{ext:run-program}, which opens pipes to communicate with the
program and manipulate it while it runs on the background.
External process is a structure created with @code{ext:run-program}
External process is a structure created with @coderef{ext:run-program}
(returned as third value). It is programmer responsibility, to call
@code{ext:external-process-wait} on finished processes, however during
@coderef{ext:external-process-wait} on finished processes, however during
garbage collection object will be finalized.
@lspdef ext:external-process-pid
@defun ext:external-process-pid process
Returns process PID or @code{nil} if already finished.
@end defun
@lspdef ext:external-process-status
@defun ext:external-process-status process
Updates process status. @code{ext:external-process-status} calls
@code{ext:external-process-wait} if process has not finished yet
Updates process status. @coderef{ext:external-process-status} calls
@coderef{ext:external-process-wait} if process has not finished yet
(non-blocking call). Returns two values:
@code{status} - member of @code{(:abort :error :exited :signalled
@ -175,40 +178,45 @@ Updates process status. @code{ext:external-process-status} calls
it is a signal code. Otherwise NIL.
@end defun
@lspdef ext:external-process-wait
@defun ext:external-process-wait process wait
If the second argument is non-NIL, function blocks until external
process is finished. Otherwise status is updated. Returns two values
(see @code{ext:external-process-status}).
(see @coderef{ext:external-process-status}).
@end defun
@lspdef ext:terminate-process
@defun ext:terminate-process process &optional force
Terminates external process.
@end defun
@lspdef ext:external-process-input
@lspdef ext:external-process-output
@lspdef ext:external-process-error-stream
@defun ext:external-process-input process
@defunx ext:external-process-output process
@defunx ext:external-process-error-stream process
Process stream accessors (read-only).
@end defun
@lspindex ext:run-program
@lspdef ext:run-program
@defun ext:run-program command argv @
&key input output error wait environ @
if-input-does-not-exist if-output-exists if-error-exists @
external-format #+windows escape-arguments
@code{run-program} creates a new process specified by the
@coderef{ext:run-program} creates a new process specified by the
@var{command} argument. @var{argv} are the standard arguments that can
be passed to a program. For no arguments, use @code{nil} (which means
that just the name of the program is passed as arg 0).
@code{run-program} will return three values - two-way stream for
@coderef{ext:run-program} will return three values - two-way stream for
communication, return code or @code{nil} (if process is called
asynchronously), and @code{ext:external-process} object holding
process state.
It is programmer responsibility to call
@code{ext:external-process-wait} on finished process, however ECL
@coderef{ext:external-process-wait} on finished process, however ECL
associates @ref{Finalization, finalizer} with the object calling it
when the object is garbage collected. If process didn't finish but is
not referenced, finalizer will be invoked once more during next
@ -216,71 +224,68 @@ garbage collection.
The @code{&key} arguments have the following meanings:
@defvr argument input
@table @var
@item input
Either @code{t}, @code{nil}, a pathname, a string, a stream or
@code{:stream}. If @code{t} the standard input for the current process
is inherited. If @code{nil}, @code{/dev/null} is used. If a pathname
(or a string), the file so specified is used. If a stream, all the
input is read from that stream and sent to the subprocess. If
@code{:stream}, the @code{external-process-input} slot is filled in
with a stream that sends its output to the process. Defaults to
@code{:stream}.
@end defvr
is inherited. If @code{nil}, @code{/dev/null} is used. If a pathname (or
a string), the file so specified is used. If a stream, all the input is
read from that stream and sent to the subprocess. If @code{:stream}, the
@coderef{ext:external-process-input} slot is filled in with a stream
that sends its output to the process. Defaults to @code{:stream}.
@defvr argument if-input-does-not-exist
can be one of: @code{:error} to generate an error @code{:create} to
@item if-input-does-not-exist
Can be one of: @code{:error} to generate an error @code{:create} to
create an empty file @code{nil} (the default) to return nil from
@code{run-program}
@end defvr
@coderef{ext:run-program}
@defvr argument output
@item output
Either @code{t}, @code{nil}, a pathname, a string, a stream, or
@code{:stream}. If @code{t}, the standard output for the current
process is inherited. If @code{nil}, @code{/dev/null} is used. If a
pathname (or as string), the file so specified is used. If a stream,
all the output from the process is written to this stream. If
@code{:stream}, the @code{external-process-output} slot is filled in
with a stream that can be read to get the output. Defaults to
@code{:stream}.
@end defvr
@code{:stream}. If @code{t}, the standard output for the current process
is inherited. If @code{nil}, @code{/dev/null} is used. If a pathname (or
as string), the file so specified is used. If a stream, all the output
from the process is written to this stream. If @code{:stream}, the
@coderef{ext:external-process-output} slot is filled in with a stream
that can be read to get the output. Defaults to @code{:stream}.
@defvr argument if-output-exists
@end defvr
@item if-output-exists
Can be one of: @code{:error} (the default) to generate an error,
@code{:supersede} to supersede the file with output from the program,
@code{:append} to append output from the program to the file or
@code{nil} to return @code{nil} from @coderef{ext:run-program}.
@defvr argument error
@item error
Same as @code{:output}, except that @code{:error} can also be
specified as @code{:output} in which case all error output is routed
to the same place as normal output. Defaults to @code{:output}.
@end defvr
@defvr argument if-error-exists
@item if-error-exists
Same as @code{:if-output-exists}.
@end defvr
@defvr argument wait
If non-NIL (default), wait until the created process finishes. If
@item wait
If non-@code{nil} (default), wait until the created process finishes. If
@code{nil}, continue running Lisp until the program finishes.
@end defvr
@defvr argument environ
@item environ
A list of STRINGs describing the new Unix environment (as in "man
environ"). The default is to copy the environment of the current
process. To extend existing environment (instead of replacing it),
use @code{:environ (append *my-env* (ext:environ))}.
If non-NIL @code{environ} argument is supplied, then first argument to
@code{ext:run-program} @code{command} must be full path to the file.
@end defvr
If non-@code{nil} @code{environ} argument is supplied, then first
argument to @coderef{ext:run-program}, @var{command}, must be full path
to the file.
@defvr argument external-format
@item external-format
The external-format to use for @code{:input}, @code{:output}, and
@code{:error} STREAMs.
@end defvr
@end table
@emph{Windows specific options:}
@defvr argument escape-arguments
Controls escaping of the arguments passed to CreateProcess.
@end defvr
@strong{Windows specific options:}
@table @var
@item escape-arguments
Controls escaping of the arguments passed to @code{CreateProcess}.
@end table
@end defun
@cindex FIFO files (named pipes)
@ -289,8 +294,8 @@ Controls escaping of the arguments passed to CreateProcess.
Named pipe (known as fifo) may be created on UNIX with a shell command
mkfifo. ECL opens such files in non-blocking
mode. @code{ext:file-kind} will return for such file
@code{:FIFO}. Since it is impossible to guess how many characters are
mode. @coderef{ext:file-kind} will return for such file
@code{:fifo}. Since it is impossible to guess how many characters are
available in this special file @code{file-length} function will return
NIL.
@ -307,15 +312,17 @@ NIL.
@c @defun ext:argv
@c @end defun
@lspdef ext:system
@defun ext:system command
Run shell command ignoring its output. Uses fork.
@end defun
@lspdef ext:make-pipe
@defun ext:make-pipe
Creates a pipe and wraps it in a two way stream.
@end defun
@lspdef ext:quit
@defun ext:quit &optional exit-code kill-all-threads
This function abruptly stops the execution of the program in which ECL
is embedded. Depending on the platform, several other functions will
@ -324,10 +331,13 @@ be invoked to free resources, close loaded modules, etc.
The exit code is the code seen by the parent process that invoked this
program. Normally a code other than zero denotes an error.
If @code{kill-all-threads} is non-NIL, tries to gently kill and join
with running threads.
If @var{kill-all-threads} is non-@code{nil}, tries to gently kill and
join with running threads.
@end defun
@lspdef ext:environ
@lspdef ext:getenv
@lspdef ext:setenv
@defun ext:environ
@defunx ext:getenv variable
@defunx ext:setenv variable value
@ -337,6 +347,14 @@ Environment accessors.
@c UNIX shell interface
@lspdef ext:getpid
@lspdef ext:getuid
@lspdef ext:getcwd
@lspdef ext:chdir
@lspdef ext:file-kind
@lspdef ext:copy-file
@lspdef ext:chmod
@defun ext:getpid
@defunx ext:getuid
@defunx ext:getcwd &optional (change-default-pathname-defaults NIL)

View file

@ -51,8 +51,8 @@ Example:
@end lisp
@end defmac
@lspindex ext:package-local-nicknames
@cppindex si_package_local_nicknames
@lspdef ext:package-local-nicknames
@cppdef si_package_local_nicknames
@defun {ext:package-local-nicknames} package-designator
@end defun
@deftypefun cl_object si_package_local_nicknames (cl_object package_designator)
@ -69,8 +69,8 @@ local nickname is used instead of the real name in order to preserve
print-read consistency.
@end deftypefun
@lspindex ext:package-locally-nicknamed-by-list
@cppindex si_package_locally_nicknamed_by_list
@lspdef ext:package-locally-nicknamed-by-list
@cppdef si_package_locally_nicknamed_by_list
@defun {ext:package-locally-nicknamed-by-list} package-designator
@end defun
@deftypefun cl_object si_package_locally_nicknamed_by_list (cl_object package_designator)
@ -78,8 +78,8 @@ Returns a list of packages which have a local nickname for the
designated package.
@end deftypefun
@lspindex ext:add-package-local-nickname
@cppindex si_add_package_local_nickname
@lspdef ext:add-package-local-nickname
@cppdef si_add_package_local_nickname
@defun {ext:add-package-local-nickname} local-nickname actual-package &optional package-designator
@end defun
@deftypefun cl_object si_add_package_local_nickname (cl_object local_nickname, cl_object actual_package, cl_object package_designator)
@ -103,14 +103,14 @@ nickname, the local nickname is used instead of the real name in order
to preserve print-read consistency.
@end deftypefun
@lspindex ext:remove-package-local-nickname
@cppindex si_remove_package_local_nickname
@lspdef ext:remove-package-local-nickname
@cppdef si_remove_package_local_nickname
@defun {ext:remove-package-local-nickname} old-nickname &optional package-designator
@end defun
@deftypefun cl_object si_remove_package_local_nickname (cl_object old_nickname, cl_object package_designator)
If the designated package had @var{old-nickname} as a local nickname
for another package, it is removed. Returns true if the nickname
existed and was removed, and @code{NIL} otherwise.
existed and was removed, and @code{nil} otherwise.
@end deftypefun
@node Package locks
@ -193,53 +193,51 @@ Removing an existing package local nickname to a package.
@subsection Package Lock Dictionary
@lspindex ext:package-locked-p
@lspdef ext:package-locked-p
@defun ext:package-locked-p package
Returns @code{t} when @code{package} is locked, @code{nil}
otherwise. Signals an error if @code{package} doesn't designate a valid
Returns @code{t} when @var{package} is locked, @code{nil}
otherwise. Signals an error if @var{package} doesn't designate a valid
package.
@end defun
@lspindex ext:lock-package
@lspdef ext:lock-package
@defun ext:lock-package package
Locks @code{package} and returns @code{t}. Has no effect if package was
Locks @var{package} and returns @code{t}. Has no effect if package was
already locked. Signals an error if package is not a valid
@code{package} designator
@var{package} designator
@end defun
@lspindex ext:unlock-package
@lspdef ext:unlock-package
@defun ext:unlock-package package
Unlocks @code{package} and returns @code{t}. Has no effect if
@code{package} was already unlocked. Signals an error if @code{package}
Unlocks @var{package} and returns @code{t}. Has no effect if
@var{package} was already unlocked. Signals an error if @var{package}
is not a valid package designator.
@end defun
@lspindex ext:without-package-locks
@lspdef ext:without-package-locks
@defmac ext:without-package-locks &body body
Ignores all runtime package lock violations during the execution of
body. Body can begin with declarations.
@end defmac
@lspindex ext:with-unlocked-packages
@lspdef ext:with-unlocked-packages
@defmac ext:with-unlocked-packages (&rest packages) &body body
Unlocks @code{packages} for the dynamic scope of the
@code{body}. Signals an error if any of @code{packages} is not a valid
Unlocks @var{packages} for the dynamic scope of the
@var{body}. Signals an error if any of @var{packages} is not a valid
package designator.
@end defmac
@defmac cl:defpackage name [[option]]* @result{} package
Options are extended to include the following:
Options are extended to include
@itemize
@item
@code{:lock} @var{boolean}
@example
:lock boolean
@end example
If the argument to @code{:lock} is @code{t}, the package is initially
locked. If @code{:lock} is not provided it defaults to @code{nil}.
@end itemize
@exindex Defpackage @code{:lock} option
Example:

View file

@ -43,7 +43,7 @@ The first family of signals are generated by the floating point processing hardw
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.
The third family is related to the multiprocessing capabilities in Common Lisp systems and more precisely to the @code{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.
The third family is related to the multiprocessing capabilities in Common Lisp systems and more precisely to the @coderef{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.
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.
@ -76,7 +76,7 @@ In systems in which this is possible, ECL creates a signal handling thread to de
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.
The installation of the signal handling thread is dictated by a boot time option, @code{ECL_OPT_SIGNAL_HANDLING_THREAD}, and it will only be possible in systems that support either POSIX or Windows threads.
The installation of the signal handling thread is dictated by a boot time option, @code{ECL_OPT_SIGNAL_HANDLING_THREAD} (@pxref{tab:boot-options} for a summary of boot options), and it will only be possible in systems that support either POSIX or Windows threads.
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.
@ -94,87 +94,46 @@ The approach in ECL is more lightweight: we install our own signal handler and u
Systems that embed ECL may wish to deactivate completely these signal handlers. This is done using the boot options, @code{ECL_OPT_TRAP_SIGFPE}, @code{ECL_OPT_TRAP_SIGSEGV}, @code{ECL_OPT_TRAP_SIGBUS}, @code{ECL_OPT_TRAP_INTERRUPT_SIGNAL}.
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 @code{si_safe_eval()}, and in all other cases it can be solved by enclosing the unsafe code in a @code{CL_CATCH_ALL_BEGIN} frame.
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 @coderef{si_safe_eval}, and in all other cases it can be solved by enclosing the unsafe code in a @coderef{CL_CATCH_ALL} frame.
@node Signals and Interrupts - Considerations when embedding ECL
@subsection Considerations when embedding ECL
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.
If you want to use your own signal handlers then you should set the appropriate options before invoking @code{cl_boot()}, as explained in @code{ecl_set_option}. Note that in this case ECL will not always be able to detect floating point exceptions.
If you want to use your own signal handlers then you should set the appropriate options before invoking @coderef{cl_boot}, as explained in @coderef{ecl_set_option}. Note that in this case ECL will not always be able to detect floating point exceptions.
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 @code{ecl_disable_interrupts} and @code{ecl_enable_interrupts} or the POSIX functions @code{pthread_sigmaks}and @code{sigprocmask}.
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 @coderef{ecl_disable_interrupts} and @coderef{ecl_enable_interrupts} or the POSIX functions @code{pthread_sigmaks} and @code{sigprocmask}.
@node Signals and Interrupts - Signals Reference
@subsection Signals Reference
@lspindex mp:with-interrupts
@lspindex mp:without-interrupts
@defmac mp:with-interrupts &body body
Execute code with interrupts optionally enabled.
@subsubheading Description
Executes the given body with all interrupts enabled. Since interrupts are normally enabled, this macro only makes sense if there is an outer @code{mp:without-interrupts} with a corresponding @code{mp:allow-with-interrupts}: interrupts are not enabled if any outer @code{mp:without-interrupts} is not accompanied by @code{mp:allow-with-interrupts}.
@defmacx mp:without-interrupts &body body
Execute code with interrupts optionally enabled/disabled, @xref{Processes dictionary}.
@end defmac
@defmac mp:without-interrupts &body body
Execute code without being interrupted.
@subsubheading Description
Executes the given body with all deferrable interrupts disabled. Deferrable interrupts arriving during execution of the body take effect after the body has been executed.
Deferrable interrupts include most blockable POSIX signals, and @code{mp:interrupt-process}. Does not interfere with garbage collection, and does not inhibit scheduling of other threads.
This macro is compatible with the one in SBCL and as such it also defines three other local macros @code{mp:allow-with-interrupts}, @code{mp:with-local-interrupts} and @code{mp:with-restored-interrupts}.
@code{mp:with-restored-interrupts} executes the body with interrupts enabled if and only if the @code{mp:without-interrupts} was in an environment in which interrupts were allowed.
@code{mp:allow-with-interrupts} allows the @code{mp:with-interrupts} to take effect during the dynamic scope of its body, unless there is an outer @code{mp:without-interrupts} without a corresponding @code{mp:allow-with-interrupts}.
@code{mp:with-local-interrupts} executes its body with interrupts enabled provided that there is an @code{mp:allow-with-interrupts} for every @code{mp:without-interrupts} surrounding the current one. @code{mp:with-local-interrupts} is equivalent to:
@lisp
(allow-with-interrupts (with-interrupts ...))
@end lisp
Care must be taken not to let either @code{mp:allow-with-interrupts} or @code{mp:with-local-interrupts} appear in a function that escapes from inside the @code{mp:without-interrupts} in:
@lisp
(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 ...)))
@end lisp
@end defmac
@lspindex ext:unix-signal-received
@lspdef ext:unix-signal-received
@deftp Condition ext:unix-signal-received
Unix signal condition
@subsubheading Class Precedence List
@code{condition, t}
@paragraph Class Precedence List
@code{condition}, @code{t}
@subsubheading Methods
@lspindex ext:unix-signal-received-code
@paragraph Methods
@lspdef ext:unix-signal-received-code
@defun ext:unix-signal-received-code condition
Returns the signal code of @code{condition}
Returns the signal code of @var{condition}
@end defun
@end deftp
@lspindex ext:get-signal-handler
@lspdef ext:get-signal-handler
@defun ext:get-signal-handler code
Queries the currently active signal handler for @var{code}.
@end defun
@lspindex ext:set-signal-handler
@lspdef ext:set-signal-handler
@defun ext:set-signal-handler code handler
Arranges for the signal @var{code} to be caught in all threads and
sets the signal handler for it. The value of @var{handler} modifies
@ -186,14 +145,14 @@ arguments
@item @var{handler} is a symbol denoting a condition type
A continuable error of the given type will be signaled
@item @var{handler} is equal to @var{code}
A condition of type @code{ext:unix-signal-received} with the
A condition of type @coderef{ext:unix-signal-received} with the
corresponding signal code will be signaled
@item @var{handler} is @code{nil}
The signal will be caught but no handler will be called
@end table
@end defun
@lspindex ext:catch-signal
@lspdef ext:catch-signal
@defun ext:catch-signal code flag &key process
Changes the action taken on receiving the signal @var{code}.
@var{flag} can be one of the following:
@ -203,7 +162,7 @@ Ignore the signal
@item @code{:default}
Use the default signal handling strategy of the operating system
@item @code{t} or @code{:catch}
Catch the signal and invoke the signal handler as given by @code{ext:get-signal-handler}
Catch the signal and invoke the signal handler as given by @coderef{ext:get-signal-handler}
@item @code{:mask}, @code{:unmask}
Change the signal mask of either a) the not yet enabled @var{process}
or b) the current process, if @var{process} is not supplied
@ -220,7 +179,7 @@ CL-USER> (ext:get-signal-handler ext:+SIGPIPE+)
NIL
CL-USER> (ext:set-signal-handler ext:+SIGPIPE+
#'(lambda ()
(format t "SIGPIPE detected in process: ~a~%" process)))
(format t "SIGPIPE detected in process: ~a~%" mp:*current-process*)))
#<bytecompiled-function 0x25ffca8>
@end lisp
Passing the SIGPIPE signal to the ECL program with @code{killall -s

View file

@ -55,6 +55,8 @@ ecl-devel@common-lisp.net.
@itemize Copyright
@item
Daniel Kochmański and Marius Gerbershagen, 2020
@item
Daniel Kochmański, 2016
@item
Juan José García-Ripoll, 2006

View file

@ -102,10 +102,10 @@
@c --- TAGS --- @
@macro cind
C/C++ identifier
{C/C++ identifier}
@end macro
@macro lind
Common Lisp symbol
{Common Lisp symbol}
@end macro
@macro ocl
@emph{Only in Common Lisp}
@ -121,3 +121,28 @@ Common Lisp symbol
\left\
@tab \right\
@end macro
@macro paragraph{title}
@b{\title\}
@end macro
@macro coderef{code}
@inlinefmtifelse{html, @code{@ref{\code\}}, @code{\code\}}
@end macro
@macro seealso{node}
@paragraph{See also}
@coderef{\node\}
@end macro
@macro cppdef{name}
@anchor{\name\}
@cppindex \name\
@end macro
@macro lspdef{name}
@anchor{\name\}
@lspindex \name\
@end macro

View file

@ -1,7 +1,7 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename ecl.info
@settitle ECL User's Guide
@settitle ECL Manual
@setchapternewpage odd
@paragraphindent none
@defcodeindex cpp
@ -47,8 +47,6 @@ Copyright @copyright{} 2000, Juan Jose Garcia Ripoll
Copyright @copyright{} 2015, Daniel Kochmański
@end titlepage
@contents
@c ************************ TOP NODE **************************
@ifnottex
@ -72,21 +70,22 @@ languages.
@menu
* Introduction:: What @ecl{} is
* User's guide:: Guide for the programmers using ECL
* Developer's guide:: Guide for the ECL developers
* Standards:: Deviations and clarifications of the standard
* Extensions:: ECL-specific features and extensions
* Developer's guide:: Guide for the ECL developers
* Indexes:: Concepts, functions, variables, types and C/C++
* Bibliography:: Some interesting books.
@c * List of Figures::
@c * List of Tables::
@end menu
@contents
@include introduction/index.txi
@include user-guide/index.txi
@include developer-guide/index.txi
@include standards/index.txi
@include extensions/index.txi
@include developer-guide/index.txi
@include indexes/index.txi
@node Bibliography

View file

@ -39,7 +39,10 @@ When the elements of an array are declared to have some precise type, such as a
@item (unsigned-byte 64) @tab uint64_t @tab 64 bits
@item single-float or short-float @tab float @tab 32-bits IEEE float
@item double-float @tab double @tab 64-bits IEEE float
@c @item long-float @tab long double @tab Between 96 and 128 bits. !Not implemented
@item long-float @tab long double @tab Between 96 and 128 bits
@item (complex single-float) @tab float _Complex @tab 64 bits
@item (complex double-float) @tab double _Complex @tab 128 bits
@item (complex long-float) @tab long double _Complex @tab Between 192 and 256 bits
@item t @tab cl_object @tab Size of a pointer.
@end multitable
@ -52,18 +55,15 @@ Let us remark that some of these specialized types might not exist in your platf
C types, limits and enumerations
@subsubheading Constants and types
@cppindex ECL_ARRAY_RANK_LIMIT
@cppindex ECL_ARRAY_DIMENSION_LIMIT
@cppindex ECL_ARRAY_TOTAL_LIMIT
@cppindex cl_elttype
@cppdef ECL_ARRAY_RANK_LIMIT
@cppdef ECL_ARRAY_DIMENSION_LIMIT
@cppdef ECL_ARRAY_TOTAL_LIMIT
@cppdef cl_elttype
@defvr Constant ECL_ARRAY_RANK_LIMIT
@end defvr
@defvr Constant ECL_ARRAY_DIMENSION_LIMIT
@end defvr
@defvr Constant ECL_ARRAY_TOTAL_LIMIT
@defvrx Constant ECL_ARRAY_DIMENSION_LIMIT
@defvrx Constant ECL_ARRAY_TOTAL_LIMIT
@end defvr
@deftp enum cl_elttype @{ecl_aet_object, ...@}
@end deftp
@multitable @columnfractions .25 .25 .25 .25
@headitem Lisp or C type @tab Enumeration value @tab Lisp or C type @tab Enumeration value
@ -79,50 +79,49 @@ C types, limits and enumerations
@item (complex single-float) @tab ecl_aet_csf @tab (complex double-float) @tab ecl_aet_cdf
@end multitable
@subsubheading Description
@paragraph Description
This list contains the constants that limit the rank of an array
(@code{ECL_ARRAY_RANK_LIMIT}), the maximum size of each dimension
(@code{ECL_ARRAY_DIMENSION_LIMIT}) and the maximum number of elements
in an array (@code{ECL_ARRAY_TOTAL_LIMIT}).
(@coderef{ECL_ARRAY_RANK_LIMIT}), the maximum size of each dimension
(@coderef{ECL_ARRAY_DIMENSION_LIMIT}) and the maximum number of elements
in an array (@coderef{ECL_ARRAY_TOTAL_LIMIT}).
ECL uses also internally a set of constants to describe the different
specialized arrays. The constants form up the enumeration type
cl_elttype. They are listed in the table above, which associates
enumeration values with the corresponding Common Lisp element type.
@coderef{cl_elttype}. They are listed in the table above, which
associates enumeration values with the corresponding Common Lisp element
type.
@end deftp
@subsubsection ecl_aet_to_symbol, ecl_symbol_to_aet
To and from element types
@subsubheading Functions
@cppindex ecl_aet_to_symbol
@cppindex ecl_symbol_to_aet
@deftypefun cl_object ecl_aet_to_symbol (cl_elttype @var{param})
@end deftypefun
@deftypefun cl_elttype ecl_symbol_to_aet (cl_object @var{type})
@end deftypefun
@cppdef ecl_aet_to_symbol
@cppdef ecl_symbol_to_aet
@deftypefun cl_object ecl_aet_to_symbol (cl_elttype param)
@deftypefunx cl_elttype ecl_symbol_to_aet (cl_object type)
@subsubheading Description
@code{ecl_aet_to_symbol} returns the Lisp type associated to the elements of that specialized array class. @code{ecl_symbol_to_aet} does the converse, computing the C constant that is associated to a Lisp element type.
@paragraph Description
@coderef{ecl_aet_to_symbol} returns the Lisp type associated to the elements of that specialized array class. @coderef{ecl_symbol_to_aet} does the converse, computing the C constant that is associated to a Lisp element type.
The functions may signal an error if any of the arguments is an invalid C or Lisp type.
@end deftypefun
@subsubsection Constructors
Creating array and vectors
@subsubheading Functions
@cppindex ecl_alloc_simple_vector
@cppindex si_make_vector
@cppindex si_make_array
@cppdef ecl_alloc_simple_vector
@cppdef si_make_vector
@cppdef si_make_array
@deftypefun cl_object ecl_alloc_simple_vector (cl_elttype element_type, cl_index length);
@end deftypefun
@deftypefun cl_object si_make_vector (cl_object element_type, cl_object length, cl_object adjustablep, cl_object fill_pointerp, cl_object displaced_to, cl_object displacement);
@end deftypefun
@deftypefun cl_object si_make_array (cl_object element_type, cl_object dimensions, cl_object adjustablep, cl_object fill_pointerp, cl_object displaced_to, cl_object displacement);
@end deftypefun
@subsubheading Description
The function @code{ecl_alloc_simple_vector} 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, @emph{element_type}, is a C constant that represents a valid array element type (See cl_elttype).
@deftypefunx cl_object si_make_vector (cl_object element_type, cl_object length, cl_object adjustablep, cl_object fill_pointerp, cl_object displaced_to, cl_object displacement);
@deftypefunx cl_object si_make_array (cl_object element_type, cl_object dimensions, cl_object adjustablep, cl_object fill_pointerp, cl_object displaced_to, cl_object displacement);
The function @code{si_make_vector} does the same job but allows creating an array with fill pointer, which is adjustable or displaced to another array.
@paragraph Description
The function @coderef{ecl_alloc_simple_vector} 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, @emph{element_type}, is a C constant that represents a valid array element type (See @coderef{cl_elttype}).
The function @coderef{si_make_vector} does the same job but allows creating an array with fill pointer, which is adjustable or displaced to another array.
@itemize
@item element_type is now a Common Lisp type descriptor, which is a symbol or list denoting a valid element type
@item dimension is a non-negative fixnum with the vector size.
@ -131,9 +130,9 @@ The function @code{si_make_vector} does the same job but allows creating an arra
@item displacement is either ECL_NIL or a non-negative value with the array displacement.
@end itemize
Finally, the function @code{si_make_array} does a similar job to @code{si_make_vector} but its second argument, @emph{dimension}, can be a list of dimensions, to create a multidimensional array.
@subsubheading Examples
Finally, the function @coderef{si_make_array} does a similar job to @coderef{si_make_vector} but its second argument, @emph{dimension}, can be a list of dimensions, to create a multidimensional array.
@paragraph Examples
Create one-dimensional @code{base-string} with room for 11 characters:
@example
@ -170,56 +169,51 @@ cl_object a = si_make_array(dims, type, ECL_NIL, /* adjustable */
ECL_NIL /* displaced_to */,
ECL_NIL /* displacement */);
@end example
@end deftypefun
@subsubsection Accessors
@cppindex ecl_aref
@cppindex ecl_aset
@cppindex ecl_aref1
@cppindex ecl_aset1
@cppdef ecl_aref
@cppdef ecl_aset
@cppdef ecl_aref1
@cppdef ecl_aset1
Reading and writing array elements
@subsubheading Functions
@deftypefun cl_object ecl_aref (cl_object array, cl_index row_major_index);
@deftypefunx cl_object ecl_aset (cl_object array, cl_index row_major_index, cl_object new_value);
@deftypefunx cl_object ecl_aref1 (cl_object vector, cl_index row_major_index);
@deftypefunx cl_object ecl_aset1 (cl_object vector, cl_index row_major_index, cl_object new_value);
@deftypefun cl_object ecl_aref (cl_object @var{array}, cl_index @var{row_major_index});
@paragraph Description
@coderef{ecl_aref} accesses an array using the supplied @emph{row_major_index}, checking the array bounds and returning a Lisp object for the value at that position. @coderef{ecl_aset} does the converse, storing a Lisp value at the given @emph{row_major_index}.
The first argument to @coderef{ecl_aref} or @coderef{ecl_aset} is an array of any number of dimensions. For an array of rank @code{N} and dimensions @code{d1, d2 ...} up to @code{dN}, the row major index associated to the indices (@code{i1,i2,...iN}) is computed using the formula @code{i1+d1*(i2+d3*(i3+...))}.
@coderef{ecl_aref1} and @coderef{ecl_aset1} are specialized versions that only work with one-dimensional arrays or vectors. They verify that the first argument is indeed a vector.
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 @code{type-error} is signaled.
@end deftypefun
@deftypefun cl_object ecl_aset (cl_object @var{array}, cl_index @var{row_major_index}, cl_object @var{new_value});
@end deftypefun
@deftypefun cl_object ecl_aref1 (cl_object @var{vector}, cl_index @var{row_major_index});
@end deftypefun
@deftypefun cl_object ecl_aset1 (cl_object @var{vector}, cl_index @var{row_major_index}, cl_object @var{new_value});
@end deftypefun
@subsubheading Description
@code{ecl_aref} accesses an array using the supplied @emph{row_major_index}, checking the array bounds and returning a Lisp object for the value at that position. @code{ecl_aset} does the converse, storing a Lisp value at the given @emph{row_major_index}.
The first argument to @code{ecl_aref} or @code{ecl_aset} is an array of any number of dimensions. For an array of rank @code{N} and dimensions @code{d1, d2 ...} up to @code{dN}, the row major index associated to the indices (@code{i1,i2,...iN}) is computed using the formula @code{i1+d1*(i2+d3*(i3+...))}.
@code{ecl_aref1} and @code{ecl_aset1} are specialized versions that only work with one-dimensional arrays or vectors. They verify that the first argument is indeed a vector.
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.
@subsubsection Array properties
@cppindex ecl_array_elttype
@cppindex ecl_array_rank
@cppindex ecl_array_dimension
@cppdef ecl_array_elttype
@cppdef ecl_array_rank
@cppdef ecl_array_dimension
Array size, fill pointer, etc.
@subsubheading Synopsis
@deftypefun cl_elttype ecl_array_elttype (cl_object @var{array});
@end deftypefun
@deftypefun cl_index ecl_array_rank (cl_object @var{array});
@end deftypefun
@deftypefun cl_index ecl_array_dimension (cl_object @var{array}, cl_index @var{index});
@end deftypefun
@subsubheading Functions
@deftypefun cl_elttype ecl_array_elttype (cl_object array);
@deftypefunx cl_index ecl_array_rank (cl_object array);
@deftypefunx cl_index ecl_array_dimension (cl_object array, cl_index index);
@subsubheading Description
@paragraph Description
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
@itemize
@item @code{ecl_array_elttype} returns the array element type, with the encoding found in the enumeration cl_elttype.
@item @code{ecl_array_rank} returns the number of dimensions of the vector or array.
@item @code{ecl_array_dimension} queries the dimension of an array, where index is a non-negative integer between 0 and @code{ecl_array_dimension(array)-1}.
@item @coderef{ecl_array_elttype} returns the array element type, with the encoding found in the enumeration cl_elttype.
@item @coderef{ecl_array_rank} returns the number of dimensions of the vector or array.
@item @coderef{ecl_array_dimension} queries the dimension of an array, where index is a non-negative integer between 0 and @code{ecl_array_dimension(array)-1}.
@end itemize
@end deftypefun
@subsubsection ANSI Dictionary
Common Lisp and C equivalence

View file

@ -11,6 +11,8 @@ ECL is fully ANSI Common-Lisp compliant in all aspects of the character data typ
@node Characters - Unicode vs. POSIX locale
@subsection Unicode vs. POSIX locale
@cfindex --enable-unicode [32|16|no]
There are two ways of building ECL: with C or with Unicode character codes. These build modes are accessed using the @code{--disable-unicode} and @code{--enable-unicode} configuration options, the last one being the default.
When using C characters we are actually relying on the char 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.
@ -62,88 +64,83 @@ Internally, ECL represents the @code{#\Newline} character by a single code. Howe
@subsection C Reference
@subsubsection C types
@cppindex ecl_base_char
@cppindex ecl_character
@cppdef ecl_base_char
@cppdef ecl_character
C character types
@subsubheading Type names
@paragraph Type names
@multitable {aaaaaaaaaaaaa} {aaaaaaaaa}
@item ecl_character @tab character
@item ecl_base_char @tab base-char
@end multitable
@subsubheading Description
ECL defines two C types to hold its characters: @code{ecl_base_char} and @code{ecl_character}.
@paragraph Description
ECL defines two C types to hold its characters: @coderef{ecl_base_char} and @coderef{ecl_character}.
@itemize
@item When ECL is built without Unicode, they both coincide and typically match @code{unsigned char}, to cover the 256 codes that are needed.
@item When ECL is built with Unicode, the two types are no longer equivalent, with @code{ecl_character} being larger.
@item When ECL is built with Unicode, the two types are no longer equivalent, with @coderef{ecl_character} being larger.
@end itemize
For your code to be portable and future proof, use both types to really express what you intend to do.
@subsubsection Constructors
@cppindex ECL_CODE_CHAR
@cppindex ECL_CHAR_CODE
@cppindex ecl_char_code
@cppindex ecl_base_char_code
@cppdef ECL_CODE_CHAR
@cppdef ECL_CHAR_CODE
@cppdef ecl_char_code
@cppdef ecl_base_char_code
Creating and extracting characters from Lisp objects
@subsubheading Functions
@deftypefun cl_object ECL_CODE_CHAR (ecl_character @var{code});
@deftypefn Macro cl_object ECL_CODE_CHAR (ecl_character code);
@deftypefnx Macro ecl_character ECL_CHAR_CODE (cl_object o);
@end deftypefn
@deftypefun ecl_character ecl_char_code (cl_object o);
@deftypefunx ecl_base_char ecl_base_char_code (cl_object o);
@paragraph Description
These functions and macros convert back and forth from C character types to Lisp. The macros @coderef{ECL_CHAR_CODE} and @coderef{ECL_CODE_CHAR} perform this coercion without checking the arguments. The functions @coderef{ecl_char_code} and @coderef{ecl_base_char_code}, on the other hand, verify that the argument has the right type and signal an error otherwise.
@end deftypefun
@deftypefun ecl_character ECL_CHAR_CODE (cl_object @var{o});
@end deftypefun
@deftypefun ecl_character ecl_char_code (cl_object @var{o});
@end deftypefun
@deftypefun ecl_base_char ecl_base_char_code (cl_object @var{o});
@end deftypefun
@subsubheading Description
These functions and macros convert back and forth from C character types to Lisp. The macros @code{ECL_CHAR_CODE} and @code{ECL_CODE_CHAR} perform this coercion without checking the arguments. The functions @code{ecl_char_code} and @code{ecl_base_char_code}, on the other hand, verify that the argument has the right type and signal an error otherwise.
@subsubsection Predicates
@cppindex ecl_base_char_p
@cppindex ecl_alpha_char_p
@cppindex ecl_alphanumeric_p
@cppindex ecl_graphic_char_p
@cppindex ecl_digit_p
@cppindex ecl_standard_char_p
@cppdef ecl_base_char_p
@cppdef ecl_alpha_char_p
@cppdef ecl_alphanumeric_p
@cppdef ecl_graphic_char_p
@cppdef ecl_digit_p
@cppdef ecl_standard_char_p
C predicates for Lisp characters
@subsubheading Functions
@deftypefun bool ecl_base_char_p (ecl_character @var{c});
@end deftypefun
@deftypefun bool ecl_alpha_char_p (ecl_character @var{c});
@end deftypefun
@deftypefun bool ecl_alphanumericp (ecl_character @var{c});
@end deftypefun
@deftypefun bool ecl_graphic_char_p (ecl_character @var{c});
@end deftypefun
@deftypefun bool ecl_digitp (ecl_character @var{c});
@end deftypefun
@deftypefun bool ecl_standard_char_p (ecl_character @var{c});
@end deftypefun
@subsubheading Description
@subsubheading Functions
@deftypefun bool ecl_base_char_p (ecl_character c);
@deftypefunx bool ecl_alpha_char_p (ecl_character c);
@deftypefunx bool ecl_alphanumericp (ecl_character c);
@deftypefunx bool ecl_graphic_char_p (ecl_character c);
@deftypefunx bool ecl_digitp (ecl_character c);
@deftypefunx bool ecl_standard_char_p (ecl_character c);
@paragraph Description
These functions are equivalent to their Lisp equivalents but return C booleans.
@end deftypefun
@subsubsection Character case
@cppindex ecl_upper_case_p
@cppindex ecl_lower_case_p
@cppindex ecl_both_case_p
@cppindex ecl_char_downcase
@cppindex ecl_char_upcase
@cppdef ecl_upper_case_p
@cppdef ecl_lower_case_p
@cppdef ecl_both_case_p
@cppdef ecl_char_downcase
@cppdef ecl_char_upcase
C functions related to the character case
@subsubheading Functions
@deftypefun bool ecl_upper_case_p (ecl_character @var{c});
@end deftypefun
@deftypefun bool ecl_lower_case_p (ecl_character @var{c});
@end deftypefun
@deftypefun bool ecl_both_case_p (ecl_character @var{c});
@end deftypefun
@deftypefun ecl_character ecl_char_downcase (ecl_character @var{c});
@end deftypefun
@deftypefun ecl_character ecl_char_upcase (ecl_character @var{c});
@end deftypefun
@subsubheading Description
@deftypefun bool ecl_upper_case_p (ecl_character c);
@deftypefunx bool ecl_lower_case_p (ecl_character c);
@deftypefunx bool ecl_both_case_p (ecl_character c);
@deftypefunx ecl_character ecl_char_downcase (ecl_character c);
@deftypefunx ecl_character ecl_char_upcase (ecl_character c);
@paragraph Description
These functions check or change the case of a character. Note that in a Unicode context, the output of these functions might not be accurate (for instance when the uppercase character has two or more codepoints).
@end deftypefun
@subsubsection ANSI Dictionary
Common Lisp and C equivalence

View file

@ -2,12 +2,11 @@
@section Conditions
@subsection C Reference
@cppindex ECL_HANDLER_CASE
@cppindex ECL_RESTART_CASE
@cppdef ECL_HANDLER_CASE
@deffn Macro ECL_HANDLER_CASE
C macro for @clhs{m_hand_1.htm,handler-case}
@subsubheading Synopsis
@paragraph Synopsis
@example
@verbatim
ECL_HANDLER_CASE_BEGIN(env,names) {
@ -18,12 +17,12 @@ ECL_HANDLER_CASE_BEGIN(env,names) {
@end verbatim
@end example
@subsubheading Description
@code{ECL_HANDLER_CASE_BEGIN} runs a block of C code with a set of error handlers bound to the names given by the list @var{names}. The subsequent @code{ECL_HANDLER_CASE} statements specify what to do when the @var{n}-th type of conditions is found, where @var{n} is an integer denoting the position of the name in the list @var{names}.
@paragraph Description
@code{ECL_HANDLER_CASE_BEGIN} runs a block of C code with a set of error handlers bound to the names given by the list @var{names}. The subsequent @coderef{ECL_HANDLER_CASE} statements specify what to do when the @var{n}-th type of conditions is found, where @var{n} is an integer denoting the position of the name in the list @var{names}.
When a condition is signaled, ECL scans the list of signal handlers, looking for matches based on @code{typep}. If the match with the highest precedence belongs to the list @var{names}, ECL will perform a non-local transfer of control to the appropriate @code{ECL_HANDLER_CASE}, passing it a @var{condition} object as unique argument.
When a condition is signaled, ECL scans the list of signal handlers, looking for matches based on @code{typep}. If the match with the highest precedence belongs to the list @var{names}, ECL will perform a non-local transfer of control to the appropriate @coderef{ECL_HANDLER_CASE}, passing it a @var{condition} object as unique argument.
The following example shows how to establish a handler for @code{ERROR} conditions. Note how the first value to @code{ECL_HANDLER_CASE} matches the position of the condition name in the list:
The following example shows how to establish a handler for @code{error} conditions. Note how the first value to @coderef{ECL_HANDLER_CASE} matches the position of the condition name in the list:
@example
@verbatim
@ -42,9 +41,10 @@ ECL_HANDLER_CASE_BEGIN(the_env, ecl_list1(error)) {
@end deffn
@cppdef ECL_RESTART_CASE
@deffn Macro ECL_RESTART_CASE
C macro for @clhs{m_rst_ca.htm,restart-case}
@subsubheading Synopsis
@paragraph Synopsis
@example
@verbatim
ECL_RESTART_CASE_BEGIN(env,names) {
@ -55,12 +55,12 @@ ECL_RESTART_CASE_BEGIN(env,names) {
@end verbatim
@end example
@subsubheading Description
@code{ECL_RESTART_CASE_BEGIN} runs a block of C code with a set of restarts bound to the names given by the list @var{names}. The subsequent @code{ECL_RESTART_CASE} statements specify what to do when the @var{n}-th restart is invoked, where @var{n} is an integer denoting the position of the name in the list @var{names}.
@paragraph Description
@code{ECL_RESTART_CASE_BEGIN} runs a block of C code with a set of restarts bound to the names given by the list @var{names}. The subsequent @coderef{ECL_RESTART_CASE} statements specify what to do when the @var{n}-th restart is invoked, where @var{n} is an integer denoting the position of the name in the list @var{names}.
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 @var{args}.
The following example shows how to establish an @var{ABORT} and a @var{USE-VALUE} restart. Note how the first value to @var{ECL_RESTART_CASE} matches the position of the restart name in the list:
The following example shows how to establish an @var{abort} and a @var{use-value} restart. Note how the first value to @coderef{ECL_RESTART_CASE} matches the position of the restart name in the list:
@example
@verbatim

View file

@ -4,34 +4,34 @@
@subsection C Reference
@subsubsection Accessors
@cppindex ECL_CONS_CAR
@cppindex ECL_CONS_CDR
@cppindex _ecl_car
@cppindex _ecl_cdr
@cppdef ECL_CONS_CAR
@cppdef ECL_CONS_CDR
@cppdef ECL_RPLACA
@cppdef ECL_RPLACD
@cppdef _ecl_car
@cppdef _ecl_cdr
@cppdef _ecl_caar
@cppdef _ecl_cadr
Accessing the elements of conses
@subsubheading Functions
@deftypefun cl_object ECL_CONS_CAR (cl_object @var{o})
@end deftypefun
@deftypefun cl_object ECL_CONS_CDR (cl_object @var{o})
@end deftypefun
@deftypefun cl_object ECL_RPLACA (cl_object @var{o}, cl_object @var{v})
@end deftypefun
@deftypefun cl_object ECL_RPLACD (cl_object @var{o}, cl_object @var{v})
@end deftypefun
@deftypefun cl_object _ecl_car (cl_object @var{o})
@end deftypefun
@deftypefun cl_object _ecl_cdr (cl_object @var{o})
@end deftypefun
@deftypefun cl_object _ecl_caar (cl_object @var{o})
@end deftypefun
@deftypefun cl_object _ecl_cadr (cl_object @var{o})
@end deftypefun
@deftypefun cl_object ECL_CONS_CAR (cl_object o)
@deftypefunx cl_object ECL_CONS_CDR (cl_object o)
@deftypefunx cl_object ECL_RPLACA (cl_object o, cl_object v)
@deftypefunx cl_object ECL_RPLACD (cl_object o, cl_object v)
@deftypefunx cl_object _ecl_car (cl_object o)
@deftypefunx cl_object _ecl_cdr (cl_object o)
@deftypefunx cl_object _ecl_caar (cl_object o)
@deftypefunx cl_object _ecl_cadr (cl_object o)
...
@subsubheading Description
@paragraph Description
These functions access the elements of objects of type cons
(@code{ECL_CONS_CAR}, @code{ECL_CONS_CDR}, @code{ECL_RPLACA} and
@code{ECL_RPLACD}) or type list (@code{_ecl_car}, @code{_ecl_cdr},
@code{_ecl_caar}, ...). They don't check the type of their arguments.
(@coderef{ECL_CONS_CAR}, @coderef{ECL_CONS_CDR}, @coderef{ECL_RPLACA}
and @coderef{ECL_RPLACD}) or type list (@coderef{_ecl_car},
@coderef{_ecl_cdr}, @coderef{_ecl_caar}, ...). They don't check the type
of their arguments.
@end deftypefun
@subsubsection ANSI Dictionary
Common Lisp and C equivalence

View file

@ -31,7 +31,7 @@ the last binding as a visible one when the byte compiler was used.
@node Minimal compilation
@subsection Minimal compilation
@cindex Bytecodes eager compilation
@lspindex si::make-lambda
@lspdef si::make-lambda
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
@ -58,11 +58,12 @@ object that can be invoked. For instance,
3
@end lisp
ECL can only execute bytecodes. When a list is passed to EVAL 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 DEFUN or DEFMACRO, the compiler
processes the lambda form to produce a suitable bytecodes object.
ECL can only execute bytecodes. When a list is passed to @code{eval} 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 @code{defun} or
@code{defmacro}, the compiler processes the lambda form to produce a
suitable bytecodes object.
@cindex Eager compilation implications
@ -95,13 +96,13 @@ 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 compile or compile-file.
in files processed by @code{compile} or @code{compile-file}.
The output of (symbol-function fun) is one of the following:
The output of @code{(symbol-function fun)} is one of the following:
@itemize
@item a function object denoting the definition of the function fun,
@item a list of the form (macro . function-object) when fun denotes a macro,
@item or simply 'special, when fun denotes a special form, such as block, if, etc.
@item a function object denoting the definition of the function @code{fun},
@item a list of the form @code{(macro . function-object)} when @code{fun} denotes a macro,
@item or simply @code{'special}, when @code{fun} denotes a special form, such as @code{block}, @code{if}, etc.
@end itemize
@cindex @code{disassemble} and @code{compile} on defined functions
@ -113,30 +114,30 @@ translated into bytecodes. Therefore, if you don't need to use compile
and disassemble on defined functions, you should issue @code{(setq
si:*keep-definitions* nil)} at the beginning of your session.
@lspindex si:*keep-definitions*
@lspdef si:*keep-definitions*
@defvr Variable {si:*keep-definitions*}
If set to @code{T} ECL will preserve the compiled function source code
If set to @code{t} ECL will preserve the compiled function source code
for disassembly and recompilation.
@end defvr
@cindex Common Lisp functions limits
@lspindex call-arguments-limit
@lspindex lambda-parameters-limit
@lspindex multiple-values-limit
@lspindex lambda-list-keywords
@lspdef call-arguments-limit
@lspdef lambda-parameters-limit
@lspdef multiple-values-limit
@lspdef lambda-list-keywords
In @ref{tab:fun-const} we list all Common Lisp values related to the limits of functions.
@float Table,tab:fun-const
@caption{Function related constants}
@multitable @columnfractions 0.3 0.7
@item call-arguments-limit
@tab 65536
@tab @code{65536}
@item lambda-parameters-limit
@tab @code{call-arguments-limit}
@item multiple-values-limit
@tab 64
@tab @code{64}
@item lambda-list-keywords
@tab @code{(&optional &rest &key &allow-other-keys &aux &whole &environment &body)}
@ -154,7 +155,7 @@ ECL is implemented using either a C or a C++ compiler. This is not a limiting fa
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.
As an example let us assume that the user wants to invoke two functions which are part of the ANSI @bibcite{ANSI} standard and thus are exported with a C name. The first example is cl_cos, which takes just one argument and has a signature @code{cl_object cl_cos(cl_object)}.
As an example let us assume that the user wants to invoke two functions which are part of the ANSI @bibcite{ANSI} standard and thus are exported with a C name. The first example is @code{cl_cos}, which takes just one argument and has a signature @code{cl_object cl_cos(cl_object)}.
@example
#include <math.h>
@ -186,83 +187,81 @@ printf("\n1 + 1 is %d\n", ecl_fixnum(two));
printf("\n1 + 1 + 1 is %d\n", ecl_fixnum(three));
@end example
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, @code{ECL_C_CALL_ARGUMENTS_LIMIT}, which is as of this writing 63. The use of this stack is transparently handled by the Common Lisp functions, such as apply, funcall and their C equivalents, and also by a set of macros, @code{cl_va_arg}, which can be used for coding functions that take an arbitrary name of arguments.
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, @code{ECL_C_CALL_ARGUMENTS_LIMIT}, which is as of this writing 63. The use of this stack is transparently handled by the Common Lisp functions, such as @code{apply}, @code{funcall} and their C equivalents, and also by a set of macros, @code{cl_va_arg}, which can be used for coding functions that take an arbitrary name of arguments.
@node C Reference
@subsection C Reference
@cppindex ecl_bds_bind
@cppindex ecl_bds_push
@defun ecl_bds_bind (cl_env_ptr @var{cl_env}, cl_object @var{var}, cl_object @var{value});
@end defun
@defun ecl_bds_push (cl_env_ptr @var{cl_env}, cl_object @var{var});
@cppdef ecl_bds_bind
@cppdef ecl_bds_push
@deftypefun void ecl_bds_bind (cl_env_ptr cl_env, cl_object var, cl_object value);
@deftypefunx void ecl_bds_push (cl_env_ptr cl_env, cl_object var);
Bind a special variable
@subsubheading Description
@paragraph Description
Establishes a variable binding for the symbol @var{var} in the Common Lisp environment @var{env}, assigning it @var{value}.
This macro or function is the equivalent of @clhs{s_let_l.htm,LET*} and @clhs{s_let_l.htm,LET}.
This macro or function is the equivalent of @clhs{s_let_l.htm,let*} and @clhs{s_let_l.htm,let}.
@code{ecl_bds_push} does a similar thing, but reuses the old value of the same variable. It is thus the equivalent of @code{(LET ((VAR VAR)) ...)}
@coderef{ecl_bds_push} does a similar thing, but reuses the old value of the same variable. It is thus the equivalent of @code{(let ((var var)) ...)}
Every variable binding must undone when no longer needed. It is best practice to match each call to @code{ecl_bds_bind} by another call to @code{ecl_bds_unwind} in the same function.
@end defun
Every variable binding must undone when no longer needed. It is best practice to match each call to @coderef{ecl_bds_bind} by another call to @coderef{ecl_bds_unwind1} in the same function.
@end deftypefun
@cppindex ecl_bds_unwind1
@cppindex ecl_bds_unwind_n
@defun ecl_bds_unwind1 (cl_env_ptr @var{cl_env});
@end defun
@defun ecl_bds_unwind_n (cl_env_ptr @var{cl_env}, int @var{n});
@cppdef ecl_bds_unwind1
@cppdef ecl_bds_unwind_n
@deftypefun void ecl_bds_unwind1 (cl_env_ptr cl_env);
@deftypefunx void ecl_bds_unwind_n (cl_env_ptr cl_env, int n);
Undo one variable binding
@subsubheading Description
@code{ecl_bds_unwind1} undoes the outermost variable binding, restoring the original value of the symbol in the process.
@paragraph Description
@coderef{ecl_bds_unwind1} undoes the outermost variable binding, restoring the original value of the symbol in the process.
@code{ecl_bds_unwind_n} does the same, but for the @var{n} last variables.
@coderef{ecl_bds_unwind_n} does the same, but for the @var{n} last variables.
Every variable binding must undone when no longer needed. It is best practice to match each call to @code{ecl_bds_bind} by another call to @code{ecl_bds_unwind} in the same function.
@end defun
Every variable binding must undone when no longer needed. It is best practice to match each call to @coderef{ecl_bds_bind} by another call to @coderef{ecl_bds_unwind1} in the same function.
@end deftypefun
@cppindex ecl_setq
@deffn Macro ecl_setq (cl_env_ptr @var{cl_env}, cl_object @var{var}, cl_object @var{value});
@cppdef ecl_setq
@deftypefun cl_object ecl_setq (cl_env_ptr cl_env, cl_object var, cl_object value);
C equivalent of setq
@subsubheading Description
@paragraph Description
Assigns @var{value} to the special variable denoted by the symbol @var{var}, in the Common Lisp environment @var{cl_env}.
This function implements a variable assignment, not a variable binding. It is thus the equivalent of @clhs{s_setq.htm,setq}.
@end deffn
@end deftypefun
@cppindex ecl_symbol_value
@defun ecl_symbol_value (cl_env_ptr @var{cl_env}, cl_object @var{var});
@subsubheading Description
@cppdef ecl_symbol_value
@deftypefun cl_object ecl_symbol_value (cl_env_ptr cl_env, cl_object var);
@paragraph Description
Retrieves the value of the special variable or constant denoted by the symbol @var{var}, in the Common Lisp environment @var{cl_env}.
This function implements the equivalent of @clhs{f_symb_5.htm,symbol-value} and works both on special variables and constants.
If the symbol is not bound, an error is signaled.
@end defun
@end deftypefun
@cppindex ecl_va_list
@cppindex ecl_va_start
@cppindex ecl_va_arg
@cppindex ecl_va_end
@cppdef ecl_va_list
@cppdef ecl_va_start
@cppdef ecl_va_arg
@cppdef ecl_va_end
@deffn Macro {typedef struct @{ ... @} ecl_va_list[1];}
@end deffn
@deffn Macro ecl_va_start (ecl_va_list @var{arglist}, @var{last_argument}, @var{narg}, @var{n_ordinary});
@deffn Macro ecl_va_start (ecl_va_list arglist, last_argument, narg, n_ordinary);
@end deffn
@deftypefn Macro cl_object ecl_va_arg (ecl_va_list @var{arglist});
@deftypefn Macro cl_object ecl_va_arg (ecl_va_list arglist);
@end deftypefn
@deftypefn Macro cl_object ecl_va_end (ecl_va_list @var{arglist});
@deftypefn Macro cl_object ecl_va_end (ecl_va_list arglist);
Accepting a variable number of arguments
@subsubheading Description
@paragraph Description
The macros above are used to code a function that accepts an arbitrary number of arguments. We will describe them in a practical example
@example
@ -283,26 +282,25 @@ cl_object my_plus(cl_narg narg, cl_object required1, ...)
@end verbatim
@end example
The first thing to do is to declare the variable that will hold the arguments. This is @var{varargs} in our example and it has the type @code{ecl_va_list}.
The first thing to do is to declare the variable that will hold the arguments. This is @var{varargs} in our example and it has the type @coderef{ecl_va_list}.
This arguments list is initialized with the @code{ecl_va_start} macro, based on the supplied number of arguments, @var{narg}, the number of required arguments which are passed as ordinary C arguments (1 in this case), the last such ordinary arguments, @var{required}, and the buffer for the argument list, @var{varargs}.
This arguments list is initialized with the @coderef{ecl_va_start} macro, based on the supplied number of arguments, @var{narg}, the number of required arguments which are passed as ordinary C arguments (1 in this case), the last such ordinary arguments, @var{required}, and the buffer for the argument list, @var{varargs}.
Once @var{varargs} has been initialized, we can retrieve these values one by one using @code{ecl_va_arg}. Note that the returned value always has the type @code{cl_object}, for it is always a Common Lisp object.
Once @var{varargs} has been initialized, we can retrieve these values one by one using @coderef{ecl_va_arg}. Note that the returned value always has the type @code{cl_object}, for it is always a Common Lisp object.
The last statement before returning the output of the function is @code{ecl_va_end}. This macro performs any required cleanup and should never be omitted.
The last statement before returning the output of the function is @coderef{ecl_va_end}. This macro performs any required cleanup and should never be omitted.
@end deftypefn
@cppindex ecl_nvalues
@cppindex ecl_nth_value
@deftypefun cl_object ecl_nvalues (cl_env_ptr @var{env});
@end deftypefun
@deftypefun cl_object ecl_nth_value (cl_env_ptr @var{env}, int @var{n});
@cppdef ecl_nvalues
@cppdef ecl_nth_value
@deftypefun cl_object ecl_nvalues (cl_env_ptr env);
@deftypefunx cl_object ecl_nth_value (cl_env_ptr env, int n);
Accessing output values
@subsubheading Description
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 @code{NIL} 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
@paragraph Description
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 @code{nil} 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
@itemize
@item @code{ecl_nvalues(env)} returns the number of values that the function actually outputs. The single argument is the lisp environment. This value is larger or equal to 0 and smaller than @code{ECL_MULTIPLE_VALUES_LIMIT}.
@ -311,7 +309,7 @@ Common Lisp functions may return zero, one or more values. In ECL, the first two
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.
@subsubheading Example
@paragraph Example
A C/C++ excerpt:
@example
@ -332,26 +330,23 @@ The somewhat equivalent Common Lisp code:
@end deftypefun
@cppindex ecl_return0
@cppindex ecl_return1
@cppindex ecl_return2
@cppindex ecl_return3
@defun ecl_return0 (cl_env_ptr @var{cl_env});
@end defun
@defun ecl_return1 (cl_env_ptr @var{cl_env}, cl_object @var{value1});
@end defun
@defun ecl_return2 (cl_env_ptr @var{cl_env}, cl_object @var{value1}, cl_object @var{value2});
@end defun
@defun ecl_return3 (cl_env_ptr @var{cl_env}, cl_object @var{value1}, cl_object @var{value2}, cl_object @var{value3});
@cppdef ecl_return0
@cppdef ecl_return1
@cppdef ecl_return2
@cppdef ecl_return3
@defmac ecl_return0 (cl_env_ptr cl_env);
@defmacx ecl_return1 (cl_env_ptr cl_env, cl_object value1);
@defmacx ecl_return2 (cl_env_ptr cl_env, cl_object value1, cl_object value2);
@defmacx ecl_return3 (cl_env_ptr cl_env, cl_object value1, cl_object value2, cl_object value3);
Returning multiple values
@subsubheading Description
@paragraph Description
Returns @var{N} 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 @var{cl_env}. This macro has to be used from a function which returns an object of type @code{cl_object}.
@end defun
@end defmac
@cppindex ECL_BLOCK_BEGIN
@cppdef ECL_BLOCK_BEGIN
@deffn Macro ECL_BLOCK_BEGIN
@example
@verbatim
@ -361,16 +356,16 @@ ECL_BLOCK_BEGIN(env,code) {
@end verbatim
@end example
@subsubheading Description
@code{ECL_BLOCK_BEGIN} establishes a block named @var{code} that becomes visible for the Common Lisp code. This block can be used then as a target for @code{cl_return}.
@paragraph Description
@coderef{ECL_BLOCK_BEGIN} establishes a block named @var{code} that becomes visible for the Common Lisp code. This block can be used then as a target for @code{cl_return}.
@var{env} must be the value of the current Common Lisp environment, obtained with @code{ecl_process_env}.
@var{env} must be the value of the current Common Lisp environment, obtained with @coderef{ecl_process_env}.
The C/C++ program has to ensure that the code in @code{ECL_BLOCK_END} gets executed, avoiding a direct exit of the block via @code{goto} or a C/C++ return.
@end deffn
@cppindex ECL_CATCH_BEGIN
@cppdef ECL_CATCH_BEGIN
@deffn Macro ECL_CATCH_BEGIN
@example
@verbatim
@ -380,20 +375,20 @@ ECL_CATCH_BEGIN(env,tag) {
@end verbatim
@end example
@subsubheading Description
@code{ECL_CATCH_BEGIN} establishes a destination for @code{throw} with the code given by @var{tag}.
@paragraph Description
@coderef{ECL_CATCH_BEGIN} establishes a destination for @code{throw} with the code given by @var{tag}.
@var{env} must be the value of the current Common Lisp environment, obtained with @code{ecl_process_env}.
@var{env} must be the value of the current Common Lisp environment, obtained with @coderef{ecl_process_env}.
The C/C++ program has to ensure that the code in @code{ECL_CATCH_END} gets executed, avoiding a direct exit of the catch block via goto or a C/C++ return.
@end deffn
@cppindex ECL_UNWIND_PROTECT_BEGIN
@cppdef ECL_UNWIND_PROTECT_BEGIN
@deffn Macro ECL_UNWIND_PROTECT_BEGIN
C macro for unwind-protect
@subsubheading Synopsis
@paragraph Synopsis
@example
@verbatim
ECL_UNWIND_PROTECT_BEGIN(env) {
@ -404,10 +399,10 @@ ECL_UNWIND_PROTECT_BEGIN(env) {
@end verbatim
@end example
@subsubheading Description
@code{ECL_UNWIND_PROTECT_BEGIN} 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 some nonlocal jump construct (@code{throw}, @code{return}, etc).
@paragraph Description
@coderef{ECL_UNWIND_PROTECT_BEGIN} 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 some nonlocal jump construct (@code{throw}, @code{return}, etc).
@var{env} must be the value of the current Common Lisp environment, obtained with @code{ecl_process_env}.
@var{env} must be the value of the current Common Lisp environment, obtained with @coderef{ecl_process_env}.
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{return} or with C++ exceptions.
@end deffn

View file

@ -13,12 +13,12 @@
@defun disassemble function-designator*
Display the assembly code of a function
@subsubheading Synopsis
@paragraph Synopsis
@table @var
@item function-designator
A symbol which is bound to a function in the global environment, or a lambda form
@end table
@subsubheading Description
@paragraph Description
As specified in ANSI @bibcite{ANSI} this function outputs the internal representation of a compiled function, or of a lambda form, as it would look after being compiled.
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.
@ -31,7 +31,7 @@ ECL only has a particular difference: it has two different compilers, one based
@defmac trace function-name*
Follow the execution of functions
@subsubheading Synopsis
@paragraph Synopsis
(trace @var{function-name*})
@table @var
@item function-name
@ -46,14 +46,14 @@ A lisp form evaluated in an special environment.
List of symbols with traced functions.
@end table
@subsubheading Description
@paragraph Description
Causes one or more functions to be traced. Each @var{function-name} 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 arguments and output of this function will be printed. Trace options will modify the amount of information and when it is printed.
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 @code{notinline} declaration for the called function.
trace returns a name list of those functions that were traced by the call to trace. If no @var{function-name} is given, @code{trace} simply returns a name list of all the currently traced functions.
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 @emph{form} accompanying the option is evaluated in an environment where @var{sys::args} contains the list of arguments to the function.
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 @var{form} accompanying the option is evaluated in an environment where @var{sys::args} contains the list of arguments to the function.
The following options are defined:
@table @asis

View file

@ -1,7 +1,7 @@
@node Evaluation and compilation
@section Evaluation and compilation
@subsection Compiler declaration @code{OPTIMIZE}
@subsection Compiler declaration @code{optimize}
@cindex Compiler declarations
@lspindex optimize
@lspindex debug
@ -9,21 +9,21 @@
@lspindex safety
@lspindex space
The @code{OPTIMIZE} declaration includes three concepts: @code{DEBUG},
@code{SPEED}, @code{SAFETY} and @code{SPACE}. Each of these declarations
The @code{optimize} declaration includes three concepts: @code{debug},
@code{speed}, @code{safety} and @code{space}. 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 compile or interpret a given
lisp form.
ECL currently does not use all these declarations, but some of them
definitely affect the speed and behavior of compiled functions. For
instance, the @code{DEBUG} declaration, as shown in
instance, the @code{debug} declaration, as shown in
@ref{tab:optimize-debug}, the value of debugging is zero, the function
will not appear in the debugger and, if redefined, some functions might
not see the redefinition.
@float Table, tab:optimize-debug
@caption{Behavior for different levels of @code{DEBUG}}
@caption{Behavior for different levels of @code{debug}}
@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {a} {a} {a} {a}
@headitem Behavior
@tab 0
@ -52,16 +52,16 @@ not see the redefinition.
@end multitable
@end float
A bit more critical is the value of @code{SAFETY} because as shown in
A bit more critical is the value of @code{safety} because as shown in
@ref{tab: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 @code{SAFETY}, and invoke
@code{RPLACA} with an object which is not a list, the consequences are
instance, if you compile with a low value of @code{safety}, and invoke
@code{rplaca} with an object which is not a list, the consequences are
unspecified.
@float Table, tab:optimize-safety
@caption{Behavior for different levels of @code{SAFETY}}
@caption{Behavior for different levels of @code{safety}}
@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {a} {a} {a} {a}
@headitem Behavior
@tab 0
@ -81,7 +81,7 @@ unspecified.
@tab N
@tab N
@item 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 @code{CAR}, @code{CDR}, etc
@item 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 @code{car}, @code{cdr}, etc
@tab Y
@tab Y
@tab N
@ -99,7 +99,7 @@ unspecified.
@tab N
@tab N
@item 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 @code{PATHNAME-TYPE}, @code{CAR}, @code{REST}, etc.
@item 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 @code{pathname-type}, @code{car}, @code{rest}, etc.
@tab Y
@tab N
@tab N
@ -120,8 +120,8 @@ compiled.
@subsection C Reference
@cppindex ecl_process_env
@deftypefn {@cind{}} cl_object cl_env_ptr ()
@cppdef ecl_process_env
@deftypefn @cind{} cl_env_ptr ecl_process_env ()
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

View file

@ -32,11 +32,11 @@ The way ECL parses a namestring is by first looking for the @var{hostname} compo
If this syntax also fails, then the namestring is not a valid pathname string and a @code{parse-error} will be signaled.
It is important to remark that in ECL, all physical namestrings result into pathnames with a version equal to @code{:NEWEST}. Pathnames which are not logical and have any other version (i. e. @code{NIL} or a number), cannot be printed readably, but can produce a valid namestring which results of ignoring the version.
It is important to remark that in ECL, all physical namestrings result into pathnames with a version equal to @code{:newest}. Pathnames which are not logical and have any other version (i. e. @code{nil} or a number), cannot be printed readably, but can produce a valid namestring which results of ignoring the version.
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 @code{.bashrc}, where the leading period indicates that the file is hidden.
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, ".*" is equivalent to (@code{MAKE-PATHNAME :NAME ".*" :TYPE NIL}), while (@code{MAKE-PATHNAME :NAME NIL :TYPE :WILD}) creates a pathname whose type is a wildcard.
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, @code{".*"} is equivalent to @code{(make-pathname :name ".*" :type nil)}, while @code{(make-pathname :name nil :type :wild)} creates a pathname whose type is a wildcard.
The following table illustrates how the physical pathnames work with practical examples.
@ -44,18 +44,18 @@ The following table illustrates how the physical pathnames work with practical e
@caption{Examples of physical namestrings}
@multitable @columnfractions .28 .12 .1 .3 .2
@headitem Namestring @tab Name @tab Type @tab Directory @tab Device
@item "foo.lsp" @tab "foo" @tab "lsp" @tab NIL @tab NIL
@item ".bashrc" @tab ".bashrc" @tab NIL @tab NIL @tab NIL
@item ".ecl.lsp" @tab ".ecl" @tab "lsp" @tab NIL @tab NIL
@item "foo.*" @tab "foo" @tab :WILD @tab NIL @tab NIL
@item "*.*" @tab :WILD @tab :WILD @tab NIL @tab NIL
@item "ecl/build/bare.lsp" @tab "bare" @tab "lsp" @tab (:relative "ecl" "build") @tab NIL
@item "ecl/build/" @tab NIL @tab NIL @tab (:relative "ecl" "build") @tab NIL
@item "../../ecl/build/" @tab NIL @tab NIL @tab (:relative :up :up "ecl" "build") @tab NIL
@item "/etc/" @tab NIL @tab NIL @tab (:absolute "etc") @tab NIL
@item "C:/etc/" @tab NIL @tab NIL @tab (:absolute "etc") @tab "C"
@item ".*" @tab ".*" @tab NIL @tab NIL @tab NIL
@item #.(MAKE-PATHNAME :TYPE "*") @tab NIL @tab :WILD @tab NIL @tab NIL
@item @code{"foo.lsp"} @tab @code{"foo"} @tab @code{"lsp"} @tab @code{nil} @tab @code{nil}
@item @code{".bashrc"} @tab @code{".bashrc"} @tab @code{nil} @tab @code{nil} @tab @code{nil}
@item @code{".ecl.lsp"} @tab @code{".ecl"} @tab @code{"lsp"} @tab @code{nil} @tab @code{nil}
@item @code{"foo.*"} @tab @code{"foo"} @tab @code{:wild} @tab @code{nil} @tab @code{nil}
@item @code{"*.*"} @tab @code{:wild} @tab @code{:wild} @tab @code{nil} @tab @code{nil}
@item @code{"ecl/build/bare.lsp"} @tab @code{"bare"} @tab @code{"lsp"} @tab @code{(:relative "ecl" "build")} @tab @code{nil}
@item @code{"ecl/build/"} @tab @code{nil} @tab @code{nil} @tab @code{(:relative "ecl" "build")} @tab @code{nil}
@item @code{"../../ecl/build/"} @tab @code{nil} @tab @code{nil} @tab @code{(:relative :up :up "ecl" "build")} @tab @code{nil}
@item @code{"/etc/"} @tab @code{nil} @tab @code{nil} @tab @code{(:absolute "etc")} @tab @code{nil}
@item @code{"C:/etc/"} @tab @code{nil} @tab @code{nil} @tab @code{(:absolute "etc")} @tab @code{"C"}
@item @code{".*"} @tab @code{".*"} @tab @code{nil} @tab @code{nil} @tab @code{nil}
@item @code{#.(make-pathname :type "*")} @tab @code{nil} @tab @code{:wild} @tab @code{nil} @tab @code{nil}
@end multitable
@end float
@ -64,16 +64,16 @@ The following table illustrates how the physical pathnames work with practical e
ECL accepts four kind of wildcards in pathnames.
@itemize
@item A single wildcard in a directory component, file name, type or version is parsed as the @code{:WILD} value. See for instance "@code{*.*}", "@code{/home/*/.bashrc}", etc
@item A single wildcard in a directory component, file name, type or version is parsed as the @code{:wild} value. See for instance "@code{*.*}", "@code{/home/*/.bashrc}", etc
@item A double wildcard in a directory component, such as in "@code{/home/**/}" is parsed as the @code{:WILD-INFERIORS}, and matches any number of directories, even nested ones, such as: @code{/home/}, @code{/home/jlr}, @code{/home/jlr/lib}, etc.
@item A double wildcard in a directory component, such as in "@code{/home/**/}" is parsed as the @code{:wild-inferiors}, and matches any number of directories, even nested ones, such as: @code{/home/}, @code{/home/jlr}, @code{/home/jlr/lib}, etc.
@item An isolated wildcard "@code{log*.txt}" matches any number of characters: @code{log.txt}, @code{log_back.txt}, etc.
@item A question mark "@code{log?.txt}" matches a single character: @code{log1.txt}, @code{log2.txt}...
@end itemize
The matching rules in Common Lisp 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 @code{/}, as in @code{#p"/my/home/directory/"}. Second to that, @code{NIL} values can only be matched by @code{NIL} and @code{:WILD}. Hence, "@code{*}" can only match files without file type. For some examples see @ref{Files - Dictionary}.
The matching rules in Common Lisp 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 @code{/}, as in @code{#p"/my/home/directory/"}. Second to that, @code{nil} values can only be matched by @code{nil} and @code{:wild}. Hence, "@code{*}" can only match files without file type. For some examples see @ref{Files - Dictionary}.
@node Filenames - C Reference
@subsection C Reference

View file

@ -15,23 +15,24 @@
Weak hash tables allow the garbage collector to reclaim some of the
entries if they are not strongly referenced elsewhere. ECL supports
four kinds of weakness in hash tables: @t{:key}, @t{:value},
@t{:key-and-value} and @t{:key-or-value}.
four kinds of weakness in hash tables: @code{:key}, @code{:value},
@code{:key-and-value} and @code{:key-or-value}.
To make hash table weak, programmer has to provide @t{:weakness}
keyword argument to @t{cl:make-hash-table} with the desired kind of
weakness value (@t{NIL} means that the hash table has only strong
To make hash table weak, programmer has to provide @code{:weakness}
keyword argument to @code{cl:make-hash-table} with the desired kind of
weakness value (@code{nil} means that the hash table has only strong
references).
For more information see
@url{https://www.haible.de/bruno/papers/cs/weak/WeakDatastructures-writeup.html,Weak
References - Data Types and Implementation} by Bruno Haible.
@lspindex hash-table-weakness
@deffn {ext} {hash-table-weakness} ht
@lspdef ext:hash-table-weakness
@defun ext:hash-table-weakness ht
Returns type of the hash table weakness. Possible return values are:
@t{:key}, @t{:value}, @t{:key-and-value}, @t{:key-or-value} or @t{NIL}.
@end deffn
@code{:key}, @code{:value}, @code{:key-and-value}, @code{:key-or-value}
or @code{nil}.
@end defun
@subsubsection Thread-safe hash tables
@cindex Synchronized hash tables
@ -39,29 +40,29 @@ Returns type of the hash table weakness. Possible return values are:
By default ECL doesn't protect hash tables from simultaneous access
for performance reasons. Read and write access may is synchronized
when @t{:synchronized} keyword argument to @t{make-hash-table} is
@t{T} - @code{(make-hash-table :synchronized t)}.
when @code{:synchronized} keyword argument to @code{make-hash-table} is
@code{t} - @code{(make-hash-table :synchronized t)}.
@lspindex hash-table-synchronized-p
@deffn {ext} {hash-table-synchronized-p} ht
Predicate answering whenever hash table is synchronized or not.
@end deffn
@lspdef ext:hash-table-synchronized-p
@defun ext:hash-table-synchronized-p ht
Predicate answering whether hash table is synchronized or not.
@end defun
@subsubsection Hash tables serialization
@cindex Hash table serialization
@lspindex hash-table-content
@deffn {ext} {hash-table-content} ht
@lspdef hash-table-content
@defun ext:hash-table-content ht
Returns freshly consed list of pairs @code{(key . val)} being contents
of the hash table.
@end deffn
@end defun
@lspindex hash-table-fill
@deffn {ext} {hash-table-fill} ht values
Fills @t{ht} with @t{values} being list of @code{(key . val)}. Hash
@lspdef ext:hash-table-fill
@defun ext:hash-table-fill ht values
Fills @var{ht} with @var{values} being list of @code{(key . val)}. Hash
table may have some content already, but conflicting keys will be
overwritten.
@end deffn
@end defun
@subsubsection Custom equivalence predicate
@cindex Hash table generic test

View file

@ -32,9 +32,9 @@ ECL supports all of the Common Lisp numeric tower, which is shown in @ref{tab:nu
@end multitable
@end float
In general, the size of a @code{FIXNUM} is determined by the word size
In general, the size of a @code{fixnum} is determined by the word size
of a machine, which ranges from 32 to 64 bits. Integers larger than
this are implemented using the @url{http://www.swox.com/gmp/, GNU
this are implemented using the @url{https://gmplib.org/, GNU
Multiprecision library}. 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.
@ -42,7 +42,7 @@ include at least the two IEEE types of 32 and 64 bits respectively.
@cindex long-float internal representation
@ftindex LONG-FLOAT
In machines where it is supported, it is possible to associate the
lisp @code{LONG-FLOAT} with the machine type @code{long double} whose
lisp @code{long-float} with the machine type @code{long double} whose
size ranges from 96 to 128 bits, and which are a bit slower.
@cindex (complex float) internal representation
@ -53,6 +53,9 @@ ratios all complex numbers are pairs of numbers.
@node Numbers - Floating point exceptions
@subsection Floating point exceptions
@cfindex --with-ieee-fp [YES|no]
@cfindex --with-fpe [YES|no]
ECL supports two ways of dealing with special floating point values,
such as Not a Number (NaN), infinity or denormalized floats, which can
occur in floating point computations. Either a condition is signaled or
@ -64,17 +67,18 @@ can be disabled at build time using the @code{--without-fpe} configure
option. Otherwise, if both @code{--with-ieee-fp} and @code{--with-fpe}
options are on, by default, a condition is signaled for invalid
operation, division by zero and floating point overflows. This can be
changed at runtime by using @code{ext:trap-fpe}. If the
@code{ECL_OPT_TRAP_SIGFPE} boot option is false, no conditions are
signaled by default (Note that in this case, if you enable trapping of
floating point exceptions with @code{ext:trap-fpe}, then you have to
install your own signal handler).
changed at runtime by using @coderef{ext:trap-fpe}. If the
@code{ECL_OPT_TRAP_SIGFPE} boot option is false (see
@ref{tab:boot-options}), no conditions are signaled by default (Note
that in this case, if you enable trapping of floating point exceptions
with @coderef{ext:trap-fpe}, then you have to install your own signal
handler).
@lspindex ext:trap-fpe
@lspdef ext:trap-fpe
@defun ext:trap-fpe condition flag
Control the signaling of the floating point exceptions
@subsubheading Synopsis
@paragraph Synopsis
@table @var
@item condition
a symbol - one of @code{last}, @code{t}, @code{division-by-zero},
@ -85,18 +89,18 @@ a symbol - one of @code{last}, @code{t}, @code{division-by-zero},
a generalized boolean
@end table
@subsubheading Description
@paragraph Description
If @var{condition} is @code{last}, @var{flag} is ignored and the
currently enabled floating point exceptions are returned in an
implementation depended format (currently an integer). Otherwise,
@var{flag} determines whether the current thread will signal a
floating point exception for the conditions passed in @var{condition}.
@var{flag} determines whether the current thread will signal a floating
point exception for the conditions passed in @var{condition}.
@var{condition} can be either a symbol denoting a single condition,
@code{t} for all conditions that are enabled by default or a value
obtained from an earlier call to @code{ext:trap-fpe} with @code{last}.
obtained from an earlier call to @coderef{ext:trap-fpe} with
@code{last}.
@subsubheading See also
@code{ECL_WITH_LISP_FPE}
@seealso{ECL_WITH_LISP_FPE}
@end defun
@ -148,37 +152,36 @@ true.
NaN values are ignored, i.e. the maximum/minimum is taken only over
the number valued parameters.
@item Rounding functions
All rounding functions signal an arithmetic-error if any of the given
parameters are not number valued or infinite.
All rounding functions signal an @code{arithmetic-error} if any of the
given parameters are not number valued or infinite.
@end table
@node Numbers - Dictionary
@subsection Dictionary
@lspindex ext:short-float-positive-infinity
@lspindex ext:short-float-negative-infinity
@lspindex ext:single-float-positive-infinity
@lspindex ext:single-float-negative-infinity
@lspindex ext:double-float-positive-infinity
@lspindex ext:double-float-negative-infinity
@lspindex ext:long-float-positive-infinity
@lspindex ext:long-float-negative-infinity
@lspdef ext:short-float-positive-infinity
@lspdef ext:short-float-negative-infinity
@lspdef ext:single-float-positive-infinity
@lspdef ext:single-float-negative-infinity
@lspdef ext:double-float-positive-infinity
@lspdef ext:double-float-negative-infinity
@lspdef ext:long-float-positive-infinity
@lspdef ext:long-float-negative-infinity
@defvr Constant {ext:@{short,single,double,long@}-float-@{positive,negative@}-infinity}
Constant positive/negative infinity for the different floating point types.
@end defvr
@lspindex ext:nan
@lspdef ext:nan
@defun ext:nan
Returns a double float NaN value. Coerce to other floating point types
to get NaN values e.g. for single floats.
@end defun
@lspindex ext:float-infinity-p
@defun ext:float-infinity-p x
@end defun
@lspdef ext:float-infinity-p
@lspindex ext:float-nan-p
@defun ext:float-nan-p x
@defun ext:float-infinity-p x
@defunx ext:float-nan-p x
Predicates to test if @var{x} is infinite or NaN.
@end defun
@ -225,13 +228,13 @@ Numeric C types understood by ECL
@item unsigned long long @tab (integer 0 ffi:c-ulong-long-max) @tab ecl_ulong_long_t @tab :ulong-long
@end multitable
@subsubheading Description
@paragraph Description
The table above shows the relation between C types and the equivalent Common Lisp types. All types are standard C99 types, except for two. First, @code{cl_fixnum} is the smallest signed integer that can fit a fixnum. Second, @code{cl_index} is the smallest unsigned integer that fits a fixnum and is typically the unsigned counterpart of @code{cl_fixnum}.
(*) @strong{DEPRECATED} Previous versions of ECL supported compilers
that did not define the long double type. The @code{ECL_LONG_DOUBLE}
macro and @code{long-double} feature will be removed in the next
release.
macro and @code{long-double} features indicating whether support for
long double was available are removed now.
@cfindex --enable-c99complex [auto]
(**) The <float> _Complex types do not exist on all platforms. When
@ -254,62 +257,63 @@ In Lisp code, check for the presence of the associated features, shown in the fo
Creating Lisp types from C numbers
@subsubheading Functions
@deftypefun cl_object ecl_make_fixnum (cl_fixnum @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_integer (cl_fixnum @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_unsigned_integer (cl_index @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_single_float (float @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_double_float (double @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_long_float (long double @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_csfloat (float _Complex @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_cdfloat (double _Complex @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_clfloat (long double _Complex @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_uint8_t (uint8_t @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_int8_t (int8_t @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_uint16_t (uint16_t @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_int16_t (int16_t @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_uint32_t (uint32_t @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_int32_t (int32_t @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_uint64_t (uint64_t @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_int64_t (int64_t @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_short_t (short @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_ushort_t (unsigned short @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_int (int @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_uint (unsigned int @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_long (long @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_ulong (unsigned long @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_long_long (long long @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_ulong_long (unsigned long long @var{n})
@end deftypefun
@deftypefun cl_object ecl_make_ratio (cl_object @var{numerator}, cl_object @var{denominator})
@end deftypefun
@deftypefun cl_object ecl_make_complex (cl_object @var{real}, cl_object @var{imag})
@end deftypefun
@cppdef ecl_make_fixnum
@cppdef ecl_make_integer
@cppdef ecl_make_unsigned_integer
@cppdef ecl_make_single_float
@cppdef ecl_make_double_float
@cppdef ecl_make_long_float
@cppdef ecl_make_csfloat
@cppdef ecl_make_cdfloat
@cppdef ecl_make_clfloat
@cppdef ecl_make_uint8_t
@cppdef ecl_make_int8_t
@cppdef ecl_make_uint16_t
@cppdef ecl_make_int16_t
@cppdef ecl_make_uint32_t
@cppdef ecl_make_int32_t
@cppdef ecl_make_uint64_t
@cppdef ecl_make_int64_t
@cppdef ecl_make_short_t
@cppdef ecl_make_ushort_t
@cppdef ecl_make_int
@cppdef ecl_make_uint
@cppdef ecl_make_long
@cppdef ecl_make_ulong
@cppdef ecl_make_long_long
@cppdef ecl_make_ulong_long
@cppdef ecl_make_ratio
@cppdef ecl_make_complex
@subsubheading Description
@deftypefun cl_object ecl_make_fixnum (cl_fixnum n)
@deftypefunx cl_object ecl_make_integer (cl_fixnum n)
@deftypefunx cl_object ecl_make_unsigned_integer (cl_index n)
@deftypefunx cl_object ecl_make_single_float (float n)
@deftypefunx cl_object ecl_make_double_float (double n)
@deftypefunx cl_object ecl_make_long_float (long double n)
@deftypefunx cl_object ecl_make_csfloat (float _Complex n)
@deftypefunx cl_object ecl_make_cdfloat (double _Complex n)
@deftypefunx cl_object ecl_make_clfloat (long double _Complex n)
@deftypefunx cl_object ecl_make_uint8_t (uint8_t n)
@deftypefunx cl_object ecl_make_int8_t (int8_t n)
@deftypefunx cl_object ecl_make_uint16_t (uint16_t n)
@deftypefunx cl_object ecl_make_int16_t (int16_t n)
@deftypefunx cl_object ecl_make_uint32_t (uint32_t n)
@deftypefunx cl_object ecl_make_int32_t (int32_t n)
@deftypefunx cl_object ecl_make_uint64_t (uint64_t n)
@deftypefunx cl_object ecl_make_int64_t (int64_t n)
@deftypefunx cl_object ecl_make_short_t (short n)
@deftypefunx cl_object ecl_make_ushort_t (unsigned short n)
@deftypefunx cl_object ecl_make_int (int n)
@deftypefunx cl_object ecl_make_uint (unsigned int n)
@deftypefunx cl_object ecl_make_long (long n)
@deftypefunx cl_object ecl_make_ulong (unsigned long n)
@deftypefunx cl_object ecl_make_long_long (long long n)
@deftypefunx cl_object ecl_make_ulong_long (unsigned long long n)
@deftypefunx cl_object ecl_make_ratio (cl_object numerator, cl_object denominator)
@deftypefunx cl_object ecl_make_complex (cl_object real, cl_object imag)
@paragraph Description
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 bignum. If on the other hand the C number is a
@ -317,99 +321,104 @@ float, double or long double, the result will be a float.
There is some redundancy in the list of functions that convert from
cl_fixnum and cl_index to lisp. On the one hand,
@code{ecl_make_fixnum} always creates a fixnum, dropping bits if
necessary. On the other hand, @code{ecl_make_integer} and
@code{ecl_make_unsigned_integer} faithfully convert to a Lisp integer,
which may be a bignum.
@coderef{ecl_make_fixnum} always creates a fixnum, dropping bits if
necessary. On the other hand, @coderef{ecl_make_integer} and
@coderef{ecl_make_unsigned_integer} faithfully convert to a Lisp
integer, which may be a bignum.
Note also that some of the constructors do not use C numbers. This is
the case of @code{ecl_make_ratio} and @code{ecl_make_complex}, because
they are composite Lisp types. When c99 complex float support is built
in @code{ecl_make_complex} will use C number for float types.
the case of @coderef{ecl_make_ratio} and @coderef{ecl_make_complex},
because they are composite Lisp types. When c99 complex float support is
built in @coderef{ecl_make_complex} will use C number for float types.
These functions or macros signal no errors.
@end deftypefun
@node Numbers - Number accessors
@subsubsection Number accessors
Unchecked conversion from Lisp types to C numbers
@subsubheading Functions
@deftypefun cl_fixnum ecl_fixnum (cl_object @var{n})
@end deftypefun
@deftypefun float ecl_single_float (cl_object @var{n})
@end deftypefun
@deftypefun double ecl_double_float (cl_object @var{n})
@end deftypefun
@deftypefun {long double} ecl_long_float (cl_object @var{n})
@end deftypefun
@deftypefun {float _Complex} ecl_csfloat (cl_object @var{n})
@end deftypefun
@deftypefun {double _Complex} ecl_cdfloat (cl_object @var{n})
@end deftypefun
@deftypefun {long double _Complex} ecl_clfloat (cl_object @var{n})
@end deftypefun
@cppdef ecl_fixnum
@cppdef ecl_single_float
@cppdef ecl_double_float
@cppdef ecl_long_float
@cppdef ecl_csfloat
@cppdef ecl_cdfloat
@cppdef ecl_clfloat
@subsubheading Description
@deftypefun cl_fixnum ecl_fixnum (cl_object n)
@deftypefunx float ecl_single_float (cl_object n)
@deftypefunx double ecl_double_float (cl_object n)
@deftypefunx {long double} ecl_long_float (cl_object n)
@deftypefunx {float _Complex} ecl_csfloat (cl_object n)
@deftypefunx {double _Complex} ecl_cdfloat (cl_object n)
@deftypefunx {long double _Complex} ecl_clfloat (cl_object n)
@paragraph Description
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.
@end deftypefun
@node Numbers - Number coercion
@subsubsection Number coercion
Checked conversion from Lisp types to C numbers
@subsubheading Functions
@deftypefun cl_fixnum ecl_to_fixnum (cl_object @var{n});
@end deftypefun
@deftypefun cl_index ecl_to_unsigned_integer (cl_object @var{n});
@end deftypefun
@deftypefun float ecl_to_float (cl_object @var{n});
@end deftypefun
@deftypefun double ecl_to_double (cl_object @var{n});
@end deftypefun
@deftypefun {long double} ecl_to_long_double (cl_object @var{n});
@end deftypefun
@deftypefun {float _Complex} ecl_to_csfloat (cl_object @var{n});
@end deftypefun
@deftypefun {double _Complex} ecl_to_cdfloat (cl_object @var{n});
@end deftypefun
@deftypefun {long double _Complex} ecl_to_clfloat (cl_object @var{n});
@end deftypefun
@deftypefun uint8_t ecl_to_uint8_t (cl_object @var{n});
@end deftypefun
@deftypefun int8_t ecl_to_int8_t (cl_object @var{n});
@end deftypefun
@deftypefun uint16_t ecl_to_uint16_t (cl_object @var{n});
@end deftypefun
@deftypefun int16_t ecl_to_int16_t (cl_object @var{n});
@end deftypefun
@deftypefun uint32_t ecl_to_uint32_t (cl_object @var{n});
@end deftypefun
@deftypefun int32_t ecl_to_int32_t (cl_object @var{n});
@end deftypefun
@deftypefun uint64_t ecl_to_uint64_t (cl_object @var{n});
@end deftypefun
@deftypefun int64_t ecl_to_int64_t (cl_object @var{n});
@end deftypefun
@deftypefun short ecl_to_short (cl_object @var{n});
@end deftypefun
@deftypefun {unsigned short} ecl_to_ushort (cl_object @var{n});
@end deftypefun
@deftypefun int ecl_to_int (cl_object @var{n});
@end deftypefun
@deftypefun {unsigned int} ecl_to_uint (cl_object @var{n});
@end deftypefun
@deftypefun long ecl_to_long (cl_object @var{n});
@end deftypefun
@deftypefun {unsigned long} ecl_to_ulong (cl_object @var{n});
@end deftypefun
@deftypefun long long ecl_to_long_long (cl_object @var{n});
@end deftypefun
@deftypefun {unsigned long} long ecl_to_ulong_long (cl_object @var{n});
@end deftypefun
@cppdef ecl_to_fixnum
@cppdef ecl_to_unsigned_integer
@cppdef ecl_to_float
@cppdef ecl_to_double
@cppdef ecl_to_long_double
@cppdef ecl_to_csfloat
@cppdef ecl_to_cdfloat
@cppdef ecl_to_clfloat
@cppdef ecl_to_uint8_t
@cppdef ecl_to_int8_t
@cppdef ecl_to_uint16_t
@cppdef ecl_to_int16_t
@cppdef ecl_to_uint32_t
@cppdef ecl_to_int32_t
@cppdef ecl_to_uint64_t
@cppdef ecl_to_int64_t
@cppdef ecl_to_short
@cppdef ecl_to_ushort
@cppdef ecl_to_int
@cppdef ecl_to_uint
@cppdef ecl_to_long
@cppdef ecl_to_ulong
@cppdef ecl_to_long_long
@cppdef ecl_to_ulong_long
@subsubheading Description
@deftypefun cl_fixnum ecl_to_fixnum (cl_object n);
@deftypefunx cl_index ecl_to_unsigned_integer (cl_object n);
@deftypefunx float ecl_to_float (cl_object n);
@deftypefunx double ecl_to_double (cl_object n);
@deftypefunx {long double} ecl_to_long_double (cl_object n);
@deftypefunx {float _Complex} ecl_to_csfloat (cl_object n);
@deftypefunx {double _Complex} ecl_to_cdfloat (cl_object n);
@deftypefunx {long double _Complex} ecl_to_clfloat (cl_object n);
@deftypefunx uint8_t ecl_to_uint8_t (cl_object n);
@deftypefunx int8_t ecl_to_int8_t (cl_object n);
@deftypefunx uint16_t ecl_to_uint16_t (cl_object n);
@deftypefunx int16_t ecl_to_int16_t (cl_object n);
@deftypefunx uint32_t ecl_to_uint32_t (cl_object n);
@deftypefunx int32_t ecl_to_int32_t (cl_object n);
@deftypefunx uint64_t ecl_to_uint64_t (cl_object n);
@deftypefunx int64_t ecl_to_int64_t (cl_object n);
@deftypefunx short ecl_to_short (cl_object n);
@deftypefunx {unsigned short} ecl_to_ushort (cl_object n);
@deftypefunx int ecl_to_int (cl_object n);
@deftypefunx {unsigned int} ecl_to_uint (cl_object n);
@deftypefunx long ecl_to_long (cl_object n);
@deftypefunx {unsigned long} ecl_to_ulong (cl_object n);
@deftypefunx {long long} ecl_to_long_long (cl_object n);
@deftypefunx {unsigned long long} ecl_to_ulong_long (cl_object n);
@paragraph Description
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.
@end deftypefun
@node Numbers - ANSI dictionary
@subsubsection ANSI dictionary

View file

@ -76,8 +76,8 @@ of such types may depend on the platform, but it includes at least the
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
(@code{cl_make_array()}, @code{cl_complex()},...), or in the form of
C/C++ constructors (@code{ecl_make_symbol()}, etc).
(@code{cl_make_array}, @code{cl_complex},...), or in the form of
C/C++ constructors (@coderef{ecl_make_symbol}, etc).
Memory allocated types must always be kept alive so that the garbage
collector does not reclaim them. This involves referencing the object
@ -107,15 +107,15 @@ described below.
@itemize
@item
Functions in the Common Lisp (@code{CL}) package are prefixed with the
characters @code{cl_}, functions in the System (@code{SI}) package are
prefix with @code{si_}, etc, etc.
Functions in the Common Lisp (@code{cl}) package are prefixed with the
characters @code{cl_}, functions in the System (@code{si}) and
Extensions (@code{ext}) package are prefix with @code{si_}, etc, etc.
@item
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,
@code{COS} maps to @code{cl_object cl_cos(cl_object)}, which takes a
single Lisp object and returns a Lisp object of type @code{FLOAT}.
@code{cos} maps to @code{cl_object cl_cos(cl_object)}, which takes a
single Lisp object and returns a Lisp object of type @code{float}.
@item
If the function takes a variable number of arguments, its signature
@ -127,9 +127,9 @@ a)}, etc.
@item
Functions return at least one value, which is either the first value
output by the function, or @code{NIL}. The extra values may be retrieved
output by the function, or @code{nil}. The extra values may be retrieved
immediately after the function call using the function
@code{ecl_nth_value}.
@coderef{ecl_nth_value}.
@end itemize
In addition to the Common Lisp core functions (@code{cl_*}), there exist

View file

@ -110,13 +110,13 @@ and the table of known symbols is shown below. Note how some symbols (@code{:cr}
@subsubsection Sequence Streams
@lspindex ext:sequence-stream
@lspdef ext:sequence-stream
@deftp {System Class} ext:sequence-stream
@subsubheading Class Precedence List
@code{ext:sequence-stream, stream, t}
@paragraph Class Precedence List
@coderef{ext:sequence-stream}, @code{stream}, @code{t}
@subsubheading Description
@paragraph Description
Sequence streams work similar to string streams for vectors. The
supplied vectors that the streams read from or write to must have a
byte sized element type, i.e. @code{(signed-byte 8)},
@ -134,12 +134,12 @@ vector, whose @code{char-code}s will be equal to the values of the
bytes comprising the character in the given external format.
@end deftp
@lspindex ext:make-sequence-input-stream
@lspdef ext:make-sequence-input-stream
@defun ext:make-sequence-input-stream vector &key (start 0) (end nil) (external-format nil)
Create a sequence input stream with the subsequence bounded by
@var{start} and @var{end} of the given vector.
@end defun
@lspindex ext:make-sequence-output-stream
@lspdef ext:make-sequence-output-stream
@defun ext:make-sequence-output-stream vector &key (external-format nil)
Create a sequence output stream.
@end defun
@ -161,10 +161,10 @@ CL-USER> *output*
@subsubsection File Stream Extensions
@lspindex ext:set-buffering-mode
@lspdef ext:set-buffering-mode
@defun ext:set-buffering-mode stream mode
Control the buffering mode of a stream
@subsubheading Synopsis
@paragraph Synopsis
@table @var
@item stream
an ANSI stream
@ -173,7 +173,7 @@ one of @code{nil}, @code{:none}, @code{:line}, @code{:line-buffered}, @code{:ful
@item returns
The supplied stream
@end table
@subsubheading Description
@paragraph Description
If @var{mode} is @code{nil} or @code{:none}, @var{stream} will not be
buffered, if it is @code{:line} or @code{:line-buffered} resp.
@code{:full} or @code{:fully-buffered}, @var{stream} will be line resp.
@ -181,28 +181,28 @@ fully buffered. If the stream does not support buffering, nothing will
happen.
@end defun
@lspindex ext:file-stream-fd
@lspdef ext:file-stream-fd
@defun ext:file-stream-fd file-stream
Return the POSIX file descriptor of @var{file-stream} as an integer
@end defun
@subsubsection External Format Extensions
@lspindex ext:all-encodings
@lspdef ext:all-encodings
@defun ext:all-encodings
Return a list of all supported external formats
@end defun
@lspindex ext:character-coding-error
@lspdef ext:character-coding-error
@deftp Condition ext:character-coding-error
Character coding error
@subsubheading Class Precedence List
@code{ext:character-coding-error, error, serious-condition, condition, t}
@paragraph Class Precedence List
@coderef{ext:character-coding-error}, @code{error}, @code{serious-condition}, @code{condition}, @code{t}
@subsubheading Methods
@lspindex ext:character-coding-error-external-format
@paragraph Methods
@lspdef ext:character-coding-error-external-format
@defun ext:character-coding-error-external-format condition
@table @var
@item returns
@ -210,20 +210,20 @@ The external format of @var{condition}
@end table
@end defun
@subsubheading Description
Superclass of @code{ext:character-encoding-error} and @code{ext:character-decoding-error}.
@paragraph Description
Superclass of @coderef{ext:character-encoding-error} and @coderef{ext:character-decoding-error}.
@end deftp
@lspindex ext:character-encoding-error
@lspdef ext:character-encoding-error
@deftp Condition ext:character-encoding-error
Character encoding error
@subsubheading Class Precedence List
@code{ext:character-encoding-error, ext:character-coding-error, error, serious-condition, condition, t}
@paragraph Class Precedence List
@coderef{ext:character-encoding-error}, @coderef{ext:character-coding-error}, @code{error}, @code{serious-condition}, @code{condition}, @code{t}
@subsubheading Methods
@lspindex ext:character-encoding-error-code
@paragraph Methods
@lspdef ext:character-encoding-error-code
@defun ext:character-encoding-error-code condition
@table @var
@item returns
@ -231,22 +231,22 @@ The character code of the character, which can't be encoded
@end table
@end defun
@subsubheading Description
@paragraph Description
Condition for characters, which can't be encoded with some external
format.
@end deftp
@lspindex ext:character-decoding-error
@lspdef ext:character-decoding-error
@deftp Condition ext:character-decoding-error
Character decoding error
@subsubheading Class Precedence List
@code{ext:character-decoding-error, ext:character-coding-error, error, serious-condition, condition, t}
@paragraph Class Precedence List
@coderef{ext:character-decoding-error}, @coderef{ext:character-coding-error}, @code{error}, @code{serious-condition}, @code{condition}, @code{t}
@subsubheading Methods
@lspindex ext:character-decoding-error-octects
@paragraph Methods
@lspdef ext:character-decoding-error-octects
@defun ext:character-decoding-error-octects condition
@table @var
@item returns
@ -255,49 +255,49 @@ can't be decoded.
@end table
@end defun
@subsubheading Description
@paragraph Description
Condition for characters, which can't be decoded with some external
format.
@end deftp
@lspindex ext:stream-encoding-error
@lspdef ext:stream-encoding-error
@deftp Condition ext:stream-encoding-error
Stream encoding error
@subsubheading Class Precedence List
@code{ext:stream-encoding-error, ext:character-encoding-error, ext:character-coding-error, stream-error, error, serious-condition, condition, t}
@paragraph Class Precedence List
@coderef{ext:stream-encoding-error}, @coderef{ext:character-encoding-error}, @coderef{ext:character-coding-error}, @code{stream-error}, @code{error}, @code{serious-condition}, @code{condition}, @code{t}
@subsubheading Description
@paragraph Description
This condition is signaled when trying to write a character to a
stream, which can't be encoded with the streams external format.
@end deftp
@lspindex ext:stream-decoding-error
@lspdef ext:stream-decoding-error
@deftp Condition ext:stream-decoding-error
Stream decoding error
@subsubheading Class Precedence List
@code{ext:stream-decoding-error, ext:character-decoding-error, ext:character-coding-error, stream-error, error, serious-condition, condition, t}
@paragraph Class Precedence List
@coderef{ext:stream-decoding-error}, @coderef{ext:character-decoding-error}, @coderef{ext:character-coding-error}, @code{stream-error}, @code{error}, @code{serious-condition}, @code{condition}, @code{t}
@subsubheading Description
@paragraph Description
This condition is signaled when trying to read a character from a
stream, which can't be decoded with the streams external format.
@end deftp
@lspindex ext:encoding-error
@lspdef ext:encoding-error
@defun ext:encoding-error stream external-format code
Signal a @code{ext:stream-encoding-error} with the given
Signal a @coderef{ext:stream-encoding-error} with the given
@var{external-format} and @var{code}. Make a restart available so
that the error can be ignored or the character can be replaced with a
different one.
@end defun
@lspindex ext:decoding-error
@lspdef ext:decoding-error
@defun ext:decoding-error stream external-format octects
Signal a @code{ext:stream-decoding-error} with the given
Signal a @coderef{ext:stream-decoding-error} with the given
@var{external-format} and @var{octets}. Make a restart available so
that the error can be ignored or the octets can be replaced with a
character.
@ -322,8 +322,8 @@ Common Lisp and C equivalence
@item @clhs{f_file_p.htm,file-length} @tab cl_object cl_file_position(cl_narg narg, cl_object file_stream, ...)
@item @clhs{f_file_s.htm,file-position} @tab cl_object cl_file_position(cl_object stream)
@item @clhs{f_finish.htm,file-string-length} @tab cl_object cl_file_string_length(cl_object stream, cl_object object)
@item @clhs{f_finish.htm,finish-output} @tab cl_object cl_finish_outputt(cl_narg narg, ...)
@item @clhs{f_finish.htm,force-output} @tab cl_object cl_force_outputt(cl_narg narg, ...)
@item @clhs{f_finish.htm,finish-output} @tab cl_object cl_finish_output(cl_narg narg, ...)
@item @clhs{f_finish.htm,force-output} @tab cl_object cl_force_output(cl_narg narg, ...)
@item @clhs{f_terpri.htm,fresh-line} @tab cl_object cl_fresh_line(cl_narg narg, ...)
@item @clhs{f_get_out.htm,get-output-stream-string} @tab cl_object cl_get_output_stream_string(cl_object string_output_stream)
@item @clhs{f_in_stm.htm,input-stream-p} @tab cl_object cl_input_stream_p(cl_object stream)

View file

@ -26,50 +26,46 @@ It is important to remember that strings with unicode characters can only be pri
@node Strings - C reference
@subsection C reference
@subsubsection Base string constructors
@cppindex ecl_alloc_adjustable_base_string
@cppindex ecl_alloc_adjustable_simple_string
@cppindex ecl_make_simple_base_string
@cppindex ecl_make_constant_base_string
@cppdef ecl_alloc_adjustable_base_string
@cppdef ecl_alloc_simple_base_string
@cppdef ecl_make_simple_base_string
@cppdef ecl_make_constant_base_string
Building strings of C data
@subsubheading Functions
@deftypefun cl_object ecl_alloc_adjustable_base_string (cl_index @var{length});
@end deftypefun
@deftypefun cl_object ecl_alloc_adjustable_simple_string (cl_index @var{length});
@end deftypefun
@deftypefun cl_object ecl_make_simple_base_string (const char* @var{data}, cl_fixnum @var{length});
@end deftypefun
@deftypefun cl_object ecl_make_constant_base_string (const char* @var{data}, cl_fixnum @var{length});
@end deftypefun
@deftypefun cl_object ecl_alloc_adjustable_base_string (cl_index length);
@deftypefunx cl_object ecl_alloc_simple_base_string (cl_index length);
@deftypefunx cl_object ecl_make_simple_base_string (const char* data, cl_fixnum length);
@deftypefunx cl_object ecl_make_constant_base_string (const char* data, cl_fixnum length);
@subsubheading Description
@paragraph Description
These are different ways to create a base string, which is a string that holds a small subset of characters, the @code{base-char}, with codes ranging from 0 to 255.
@code{ecl_alloc_simple_base_string} creates an empty string with that much space for characters and a fixed length. The string does not have a fill pointer and cannot be resized, and the initial data is unspecified
@coderef{ecl_alloc_simple_base_string} creates an empty string with that much space for characters and a fixed length. The string does not have a fill pointer and cannot be resized, and the initial data is unspecified
@code{ecl_alloc_adjustable_base_string} is similar to the previous function, but creates an adjustable string with a fill pointer. This means that the length of the string can be changed and the string itself can be resized to accommodate more data.
@coderef{ecl_alloc_adjustable_base_string} is similar to the previous function, but creates an adjustable string with a fill pointer. This means that the length of the string can be changed and the string itself can be resized to accommodate more data.
The other constructors create strings but use some preexisting data. @code{ecl_make_simple_base_string} creates a string copying the data that the user supplies, and using freshly allocated memory. @code{ecl_make_constant_base_string} 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. If the @var{length} argument of these functions is -1, the length is determined by @code{strlen}.
The other constructors create strings but use some preexisting data. @coderef{ecl_make_simple_base_string} creates a string copying the data that the user supplies, and using freshly allocated memory. @coderef{ecl_make_constant_base_string} 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. If the @var{length} argument of these functions is -1, the length is determined by @code{strlen}.
@end deftypefun
@subsubsection String accessors
@cppindex ecl_char
@cppindex ecl_char_set
@cppdef ecl_char
@cppdef ecl_char_set
Reading and writing characters into a string
@subsubheading Functions
@deftypefun ecl_character ecl_char (cl_object @var{string}, cl_index @var{index});
@end deftypefun
@deftypefun ecl_character ecl_char_set (cl_object @var{string}, cl_index @var{index}, ecl_character @var{c});
@end deftypefun
@deftypefun ecl_character ecl_char (cl_object string, cl_index index);
@deftypefunx ecl_character ecl_char_set (cl_object string, cl_index index, ecl_character c);
@subsubheading Description
Access to string information should be done using these two functions. The first one implements the equivalent of the @code{CHAR} function from Common Lisp, returning the character that is at position @var{index} in the string @var{string}.
@paragraph Description
Access to string information should be done using these two functions. The first one implements the equivalent of the @code{char} function from Common Lisp, returning the character that is at position @var{index} in the string @var{string}.
The counterpart of the previous function is @code{ecl_char_set}, which implements @code{(SETF CHAR)} and stores character @var{c} at the position @var{index} in the given string.
The counterpart of the previous function is @coderef{ecl_char_set}, which implements @code{(setf char)} and stores character @var{c} at the position @var{index} in the given string.
Both functions check the type of their arguments and verify that the indices do not exceed the string boundaries. Otherwise they signal a @code{serious-condition}.
@end deftypefun
@subsubsection ANSI dictionary
Common Lisp and C equivalence

View file

@ -4,22 +4,21 @@
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 @code{#'make-symbol} or returned from @code{#'symbol-name}.
@subsection C Reference
@cppindex ecl_make_keyword
@cppindex ecl_make_symbol
@deftypefun cl_object ecl_make_keyword (char * @var{name});
@cppdef ecl_make_keyword
@deftypefun cl_object ecl_make_keyword (char *name);
Find a lisp keyword
@subsubheading Description
@paragraph Description
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 @code{KEYWORD} package. This function does the task of finding or creating those keywords from C strings.
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 @code{keyword} package. This function does the task of finding or creating those keywords from C strings.
@itemize
@item 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).
@item Remember that the case of the string is significant. @code{ecl_make_keyword("TO")} with return @code{:TO}, while @code{ecl_make_keyword("to")} returns a completely different keyword, @code{:|to|}. In short, you usually want to use uppercase.
@end itemize
@subsubheading Example
@paragraph Example
The following example converts a section of a string to uppercase characters:
@example
@ -32,11 +31,15 @@ sup = cl_string_upcase(4, s, start, ecl_make_fixnum(2),
@end deftypefun
@deftypefun cl_object ecl_make_symbol (const char * @var{name}, const char * @var{package_name});
@cppdef ecl_make_symbol
@deftypefun cl_object ecl_make_symbol (const char *name, const char *package_name);
Find a lisp symbol
@subsubheading Description
This function finds or create a symbol in the given package. First of all, it tries to find the package named by @var{package_name}. If it does not exist, an error is signaled. Then, a symbol with the suppled @var{name} is searched in the given package. If the symbol exists, it is returned. If it does not exist, using @code{INTERN}.
@paragraph Description
This function finds or create a symbol in the given package. First of
all, it tries to find the package named by @var{package_name}. If it
does not exist, an error is signaled. Then, a symbol with the supplied
@var{name} is created and interned in the given package.
@end deftypefun

View file

@ -3,11 +3,12 @@
@lspindex single-float
@lspindex double-float
ECL defines the following additional built-in classes in the @code{CL} package:
ECL defines the following additional built-in classes in the @code{cl} package:
@itemize
@item @code{single-float}
@item @code{double-float}
@item @code{long-float}
@end itemize
@subsection C Reference

View file

@ -152,5 +152,5 @@ make install
@end verbatim
@end example
Library and assets are installed in the @code{ecl-android} directory
Library and assets are installed in the "ecl-android" directory
and are ready to run on the Android system.

View file

@ -11,11 +11,11 @@
@node Embedding ECL - Embedding Reference
@subsection Embedding Reference
@cppindex CL_CATCH_ALL
@cppdef CL_CATCH_ALL
@defmac CL_CATCH_ALL
Create a protected region.
@subsubheading C Macro
@paragraph C Macro
@example
@verbatim
cl_env_ptr env = ecl_process_env();
@ -37,8 +37,8 @@ CL_CATCH_ALL_BEGIN(env) {
@end verbatim
@end example
@subsubheading Description
This is a set of three macros that create an @code{UNWIND-PROTECT} region that prevents any nonlocal transfer of control to outer loops. In the Lisp speak, the previous code is equivalent to
@paragraph Description
This is a set of three macros that create an @code{unwind-protect} region that prevents any nonlocal transfer of control to outer loops. In the Lisp speak, the previous code is equivalent to
@lisp
(block nil
@ -49,19 +49,17 @@ This is a set of three macros that create an @code{UNWIND-PROTECT} region that p
(return nil)))
@end lisp
As explained in @code{CL_UNWIND_PROTECT},it is normally advisable to set up an unwind-protect frame to avoid the embedded lisp code to perform arbitrary transfers of control.
@subsubheading See also
@code{CL_UNWIND_PROTECT}
As explained in @coderef{CL_UNWIND_PROTECT}, it is normally advisable to set up an unwind-protect frame to avoid the embedded lisp code to perform arbitrary transfers of control.
@seealso{CL_UNWIND_PROTECT}
@end defmac
@cppindex CL_UNWIND_PROTECT
@cppdef CL_UNWIND_PROTECT
@defmac CL_UNWIND_PROTECT
Create a protected region.
@subsubheading C Macro
@paragraph C Macro
@example
@verbatim
cl_env_ptr env = ecl_process_env();
@ -85,23 +83,20 @@ CL_UNWIND_PROTECT_BEGIN(env) {
@end verbatim
@end example
@subsubheading Description
@paragraph Description
When embedding ECL it is normally advisable to set up an @code{unwind-protect} frame to avoid the embedded lisp code to perform arbitrary transfers of control. Furthermore, the unwind protect form will be used in at least in the following occasions:
@itemize
@item In a normal program exit, caused by @code{ext:quit}, ECL unwinds up to the outermost frame, which may be an @code{CL_CATCH_ALL} or @code{CL_UNWIND_PROTECT} macro.
@item In a normal program exit, caused by @coderef{ext:quit}, ECL unwinds up to the outermost frame, which may be an @coderef{CL_CATCH_ALL} or @coderef{CL_UNWIND_PROTECT} macro.
@end itemize
Besides this, normal mechanisms for exit, such as @code{ext:quit}, and uncaught exceptions, such as serious signals (@xref{Signals and Interrupts - Synchronous signals}), are best handled using @code{unwind-protect} blocks.
@subsubheading See also
@code{CL_CATCH_ALL}
Besides this, normal mechanisms for exit, such as @coderef{ext:quit}, and uncaught exceptions, such as serious signals (@xref{Signals and Interrupts - Synchronous signals}), are best handled using @code{unwind-protect} blocks.
@seealso CL_CATCH_ALL
@end defmac
@cppindex cl_boot
@deftypefun int cl_boot (int @var{argc}, char **@var{argv});
@cppdef cl_boot
@deftypefun int cl_boot (int argc, char **argv);
Setup the lisp environment.
@table @var
@item argc
@ -110,20 +105,21 @@ An integer with the number of arguments to this program.
A vector of strings with the arguments to this program.
@end table
@subsubheading Description
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 @code{ecl_set_option} and @code{ecl_get_option}.
@paragraph Description
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 @coderef{ecl_set_option} and @coderef{ecl_get_option}.
@end deftypefun
@cppindex cl_shutdown
@cppdef cl_shutdown
@deftypefun int cl_shutdown (void);
Close the lisp environment.
@subsubheading Description
@paragraph Description
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.
@end deftypefun
@cppdef ecl_set_option
@deftypefun void ecl_set_option (int option, cl_fixnum value);
Set a boot option.
@ -134,7 +130,7 @@ An integer from @ref{tab:boot-options}.
A @code{cl_index} value for this option
@end table
@subsubheading Description
@paragraph Description
This functions sets the value of different options that have to be customized @emph{before} ECL boots. The table of options and default values [@ref{tab:boot-options}] shows that some of them are boolean, and some of them are unsigned integers.
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 , floating point exceptions, etc.
@ -145,14 +141,14 @@ The second set is related to the sizes of different stacks. Currently ECL uses f
@caption{Boot options for embedded ECL}
@multitable @columnfractions .3 .15 .16 .39
@headitem Name @code{(ECL_OPT_*)} @tab Type @tab Default @tab Description
@item @code{INCREMENTAL_GC} @tab boolean @tab @code{TRUE} @tab Activate generational garbage collector.
@item @code{TRAP_SIGSEGV} @tab boolean @tab @code{TRUE} @tab Capture @code{SIGSEGV} signals.
@item @code{TRAP_SIGFPE} @tab boolean @tab @code{TRUE} @tab Capture floating point exceptions.
@item @code{TRAP_SIGINT} @tab boolean @tab @code{TRUE} @tab Capture user interrupts.
@item @code{TRAP_SIGILL} @tab boolean @tab @code{TRUE} @tab Capture @code{SIGILL} exception.
@item @code{TRAP_INTERRUPT_SIGNAL} @tab boolean @tab @code{TRUE} @tab Capture the signal that implements @code{mp:interrupt-process}.
@item @code{SIGNAL_HANDLING_THREAD} @tab boolean @tab @code{TRUE} @tab Create a signal to capture and process asynchronous threads (@xref{Signals and Interrupts - Asynchronous signals}).
@item @code{BOOTED} @tab boolean @tab @code{TRUE}/@code{FALSE} @tab Has ECL booted (read only).
@item @code{INCREMENTAL_GC} @tab boolean @tab TRUE @tab Activate generational garbage collector.
@item @code{TRAP_SIGSEGV} @tab boolean @tab TRUE @tab Capture @code{SIGSEGV} signals.
@item @code{TRAP_SIGFPE} @tab boolean @tab TRUE @tab Capture floating point exceptions.
@item @code{TRAP_SIGINT} @tab boolean @tab TRUE @tab Capture user interrupts.
@item @code{TRAP_SIGILL} @tab boolean @tab TRUE @tab Capture @code{SIGILL} exception.
@item @code{TRAP_INTERRUPT_SIGNAL} @tab boolean @tab TRUE @tab Capture the signal that implements @coderef{mp:interrupt-process}.
@item @code{SIGNAL_HANDLING_THREAD} @tab boolean @tab TRUE @tab Create a signal to capture and process asynchronous threads (@xref{Signals and Interrupts - Asynchronous signals}).
@item @code{BOOTED} @tab boolean @tab TRUE/FALSE @tab Has ECL booted (read only).
@item @code{BIND_STACK_SIZE} @tab cl_index @tab 8192 @tab Size of stack for binding special variables.
@item @code{BIND_STACK_SAFETY_AREA} @tab cl_index @tab 128 @tab
@item @code{FRAME_STACK_SIZE} @tab cl_index @tab 2048 @tab Size of stack for nonlocal jumps.
@ -167,59 +163,59 @@ The second set is related to the sizes of different stacks. Currently ECL uses f
@end deftypefun
@cppindex ecl_get_option
@deftypefun cl_fixnum ecl_get_option (int @var{option});
@cppdef ecl_get_option
@deftypefun cl_fixnum ecl_get_option (int option);
Read the value of a boot option.
@table @var
@item option
An integer from @ref{tab:boot-options}.
@end table
@subsubheading Description
@paragraph Description
This functions reads the value of different options that have to be customized @emph{before} ECL boots. The table of options and default values is @ref{tab:boot-options}.
@end deftypefun
@cppindex ecl_clear_interrupts
@cppdef ecl_clear_interrupts
@defmac ecl_clear_interrupts ()
Clear all pending signals and exceptions.
@subsubheading Description
@paragraph Description
This macro clears all pending interrupts.
@subsubheading See also
@code{ecl_disable_interrupts} and @code{ecl_enable_interrupts}.
@paragraph See also
@coderef{ecl_disable_interrupts} and @coderef{ecl_enable_interrupts}.
@end defmac
@cppindex ecl_disable_interrupts
@cppdef ecl_disable_interrupts
@defmac ecl_disable_interrupts ()
Postpone handling of signals and exceptions.
@subsubheading Description
This macro sets a thread-local flag indicating that all received signals should be queued for later processing. Note that it is not possible to execute lisp code while interrupts are disabled in this way. For this purpose, use the @code{ext:without-interrupts} macro. Every call to @code{ecl_disable_interrupts} must be followed by a corresponding call to @code{ecl_enable_interrupts}, else race conditions will appear.
@paragraph Description
This macro sets a thread-local flag indicating that all received signals should be queued for later processing. Note that it is not possible to execute lisp code while interrupts are disabled in this way. For this purpose, use the @coderef{mp:without-interrupts} macro. Every call to @coderef{ecl_disable_interrupts} must be followed by a corresponding call to @coderef{ecl_enable_interrupts}, else race conditions will appear.
@subsubheading See also
@code{ecl_enable_interrupts} and @code{ecl_clear_interrupts}.
@paragraph See also
@coderef{ecl_enable_interrupts} and @coderef{ecl_clear_interrupts}.
@end defmac
@cppindex ecl_enable_interrupts
@cppdef ecl_enable_interrupts
@defmac ecl_enable_interrupts();
Activate handling of signals and exceptions.
@subsubheading Description
@paragraph Description
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.
@subsubheading See also
@code{ecl_disable_interrupts} and @code{ecl_clear_interrupts}.
@paragraph See also
@coderef{ecl_disable_interrupts} and @coderef{ecl_clear_interrupts}.
@end defmac
@cppindex ECL_WITH_LISP_FPE
@cppdef ECL_WITH_LISP_FPE
@defmac ECL_WITH_LISP_FPE
Execute Lisp code with correct floating point environment
@subsubheading Description
@paragraph Description
Unless floating point exceptions are disabled (via the
@code{--without-fpe} configure option or @code{ECL_OPT_TRAP_SIGFPE}
runtime option), ECL will change the floating point environment when
@ -227,11 +223,11 @@ booting. This macro allows for execution of Lisp code while saving and
later restoring the floating point environment of surrounding C code
so that changes in the floating point environment don't leak outside.
@code{ECL_WITH_LISP_FPE} can be also used before ECL has booted or
@coderef{ECL_WITH_LISP_FPE} can be also used before ECL has booted or
before ECL has been attached to a newly created thread.
@exindex Safely executing Lisp code with floating point exceptions in embedding program
@subsubheading Example
@paragraph Example
@example
@verbatim
#include <ecl/ecl.h>
@ -264,7 +260,6 @@ will output
inf 0
@end verbatim
@subsubheading See also
@code{ext:trap-fpe}
@seealso{ext:trap-fpe}
@end defmac

View file

@ -25,7 +25,7 @@ The number in the @ecl{} banner identifies the revision of
Unless user specifies @code{--norc} flag when invoking the @ecl{}, it
will look for the initialization files @file{~/.ecl} and
@file{~/.eclrc}. If he wants to load his own file from the current
directory, then he should pass the file path to the @code{-load}
directory, then he should pass the file path to the @code{--load}
parameter:
@example
% ecl --norc --load init.lisp
@ -42,7 +42,7 @@ Type :h for Help. Top level.
The prompt indicates that @ecl{} is now ready to receive a form from the
terminal and to evaluate it.
Usually, the current package (i.e., the value of @var{*package*}) is the
Usually, the current package (i.e., the value of @code{*package*}) 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
with the package name.
@ -55,7 +55,7 @@ COMMON-LISP> (in-package "SYSTEM")
SI>
@end example
To exit from @ecl{}, call the function @code{quit}.
To exit from @ecl{}, call the function @coderef{ext:quit}.
@example
> (quit)
@ -110,7 +110,7 @@ Broken at FOO. In: #<process TOP-LEVEL>.
`@code{>>}' 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 @code{user} package.
name, if the current package is other than the @code{cl-user} package.
To go back to the top-level loop, type @code{:q}