mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-11 22:31:12 +02:00
Docstring and manual updates.
This commit is contained in:
parent
c17c13898b
commit
d6b977a640
15 changed files with 993 additions and 538 deletions
|
@ -1,3 +1,28 @@
|
|||
2002-03-16 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* scheme-utility.texi (Hooks): Further updates merged from
|
||||
unstable branch.
|
||||
|
||||
* guile.texi (Top): Remove menu items for Handling Errors and I/O
|
||||
Extensions chapters. Move item for Obtaining and Installing
|
||||
Guile.
|
||||
|
||||
* appendices.texi (Obtaining and Installing Guile): Moved to
|
||||
intro.texi.
|
||||
|
||||
* scheme-indices.texi (R5RS Index): Make index chapters
|
||||
unnumbered.
|
||||
|
||||
* scm.texi (Handling Errors): Chapter moved to section in
|
||||
scheme-control.texi.
|
||||
(I/O Extensions): Chapter moved to section in scheme-io.texi.
|
||||
|
||||
* scheme-options.texi (Install Config): Copy doc for
|
||||
%guile-build-info from unstable branch.
|
||||
(Feature Tracking): New, copied from unstable branch.
|
||||
|
||||
* scheme-utility.texi (Hooks): Merge updates from unstable branch.
|
||||
|
||||
2002-03-15 Thien-Thi Nguyen <ttn@giblet.glug.org>
|
||||
|
||||
* tools.texi (guile-1.4 guile-snarf): Remove this node.
|
||||
|
|
|
@ -1,104 +1,3 @@
|
|||
@node Obtaining and Installing Guile
|
||||
@appendix Obtaining and Installing Guile
|
||||
|
||||
Here is the information you will need to get and install Guile and extra
|
||||
packages and documentation you might need or find interesting.
|
||||
|
||||
@menu
|
||||
* The Basic Guile Package::
|
||||
* Packages not shipped with Guile::
|
||||
@end menu
|
||||
|
||||
@node The Basic Guile Package
|
||||
@section The Basic Guile Package
|
||||
|
||||
Guile can be obtained from the main GNU archive site
|
||||
@url{ftp://prep.ai.mit.edu/pub/gnu} or any of its mirrors. The file
|
||||
will be named guile-version.tar.gz. The current version is
|
||||
@value{VERSION}, so the file you should grab is:
|
||||
|
||||
@url{ftp://prep.ai.mit.edu/pub/gnu/guile-@value{VERSION}.tar.gz}
|
||||
|
||||
To unbundle Guile use the instruction
|
||||
@example
|
||||
zcat guile-@value{VERSION}.tar.gz | tar xvf -
|
||||
@end example
|
||||
which will create a directory called @file{guile-@value{VERSION}} with
|
||||
all the sources. You can look at the file @file{INSTALL} for detailed
|
||||
instructions on how to build and install Guile, but you should be able
|
||||
to just do
|
||||
@example
|
||||
cd guile-@value{VERSION}
|
||||
./configure
|
||||
make install
|
||||
@end example
|
||||
|
||||
This will install the Guile executable @file{guile}, the Guile library
|
||||
@file{libguile.a} and various associated header files and support
|
||||
libraries. It will also install the Guile tutorial and reference manual.
|
||||
|
||||
@c [[include instructions for getting R5RS]]
|
||||
|
||||
Since this manual frequently refers to the Scheme ``standard'', also
|
||||
known as R5RS, or the
|
||||
@iftex
|
||||
``Revised$^5$ Report on the Algorithmic Language Scheme'',
|
||||
@end iftex
|
||||
@ifinfo
|
||||
``Revised^5 Report on the Algorithmic Language Scheme'',
|
||||
@end ifinfo
|
||||
we have included the report in the Guile distribution;
|
||||
@xref{Top, , Introduction, r5rs, Revised(5) Report on the Algorithmic
|
||||
Language Scheme}.
|
||||
This will also be installed in your info directory.
|
||||
|
||||
|
||||
@node Packages not shipped with Guile
|
||||
@section Packages not shipped with Guile
|
||||
|
||||
We ship the Guile tutorial and reference manual with the Guile
|
||||
distribution. Since the Scheme standard (R5RS) is a stable document, we
|
||||
ship that too.
|
||||
|
||||
Here are references (usually World Wide Web URLs) to some other freely
|
||||
redistributable documents and packages which you might find useful if
|
||||
you are using Guile.
|
||||
|
||||
@table @strong
|
||||
@item SCSH
|
||||
the Scheme Shell. Gary Houston has ported SCSH to Guile. The relevant
|
||||
chapter (@pxref{The Scheme shell (scsh)}) has references to the SCSH web
|
||||
page with all its documentation.
|
||||
|
||||
@item SLIB
|
||||
a portable Scheme library maintained by Aubrey Jaffer. SLIB can be
|
||||
obtained by ftp from @url{ftp://prep.ai.mit.edu/pub/gnu/jacal/}.
|
||||
|
||||
The SLIB package should be unpacked somewhere in Guile's load path. It
|
||||
will typically be unpacked in @file{/usr/local/share/guile/site}, so
|
||||
that it will be @file{/usr/local/share/guile/site/slib}.
|
||||
|
||||
Guile might have been installed with a different prefix, in which case
|
||||
the load path can be checked from inside the interpreter with:
|
||||
|
||||
@smalllisp
|
||||
guile> %load-path
|
||||
("/usr/local/share/guile/site" "/usr/local/share/guile/1.3a" "/usr/local/share/guile" ".")
|
||||
@end smalllisp
|
||||
|
||||
The relevant chapter (@pxref{SLIB}) has details on how to use SLIB with
|
||||
Guile.
|
||||
|
||||
@item JACAL
|
||||
a symbolic math package by Aubrey Jaffer. The latest version of Jacal
|
||||
can be obtained from @url{ftp://prep.ai.mit.edu/pub/gnu/jacal/}, and
|
||||
should be unpacked in @file{/usr/local/share/guile/site/slib} so that
|
||||
it will be in @file{/usr/local/share/guile/site/slib/jacal}.
|
||||
|
||||
The relevant section (@pxref{JACAL}) has details on how to use Jacal.
|
||||
@end table
|
||||
|
||||
|
||||
@page
|
||||
@node Debugger User Interface
|
||||
@appendix Debugger User Interface
|
||||
|
|
|
@ -94,7 +94,7 @@ by the Free Software Foundation.
|
|||
@sp 10
|
||||
@comment The title is printed in a large font.
|
||||
@title Guile Reference Manual
|
||||
@subtitle $Id: guile.texi,v 1.2.2.10 2002-03-15 14:12:58 ossau Exp $
|
||||
@subtitle $Id: guile.texi,v 1.2.2.11 2002-03-16 13:35:23 ossau Exp $
|
||||
@subtitle For use with Guile @value{VERSION}
|
||||
|
||||
@c AUTHORS
|
||||
|
@ -204,6 +204,7 @@ Part I: Introduction to Guile
|
|||
|
||||
* What is Guile?:: And what does it do?
|
||||
* Whirlwind Tour:: An introductory whirlwind tour.
|
||||
* Obtaining and Installing Guile::
|
||||
* Reporting Bugs:: Reporting bugs in Guile or this manual.
|
||||
|
||||
Part II: Guile Scheme
|
||||
|
@ -252,13 +253,10 @@ Part V: Extending Applications Using Guile
|
|||
* Libguile Intro:: Using Guile as an extension language.
|
||||
* Data Representation:: Data representation in Guile.
|
||||
* Scheme Primitives:: Writing Scheme primitives in C.
|
||||
* I/O Extensions:: Using and extending ports in C.
|
||||
* Handling Errors:: How to handle errors in C code.
|
||||
* GH:: The deprecated GH interface.
|
||||
|
||||
Appendices
|
||||
|
||||
* Obtaining and Installing Guile::
|
||||
* Debugger User Interface::
|
||||
|
||||
Indices
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
@c $Id: intro.texi,v 1.1.2.6 2002-03-15 09:23:18 ossau Exp $
|
||||
|
||||
|
||||
@page
|
||||
@node What is Guile?
|
||||
@chapter What is Guile?
|
||||
|
@ -853,6 +850,110 @@ There is also a way to manipulate the module system from C but only
|
|||
Scheme files can be autoloaded. Thus, we recommend that you define
|
||||
your modules in Scheme.
|
||||
|
||||
|
||||
@page
|
||||
@node Obtaining and Installing Guile
|
||||
@chapter Obtaining and Installing Guile
|
||||
|
||||
Here is the information you will need to get and install Guile and extra
|
||||
packages and documentation you might need or find interesting.
|
||||
|
||||
@menu
|
||||
* The Basic Guile Package::
|
||||
* Packages not shipped with Guile::
|
||||
@end menu
|
||||
|
||||
|
||||
@node The Basic Guile Package
|
||||
@section The Basic Guile Package
|
||||
|
||||
Guile can be obtained from the main GNU archive site
|
||||
@url{ftp://prep.ai.mit.edu/pub/gnu} or any of its mirrors. The file
|
||||
will be named guile-version.tar.gz. The current version is
|
||||
@value{VERSION}, so the file you should grab is:
|
||||
|
||||
@url{ftp://prep.ai.mit.edu/pub/gnu/guile-@value{VERSION}.tar.gz}
|
||||
|
||||
To unbundle Guile use the instruction
|
||||
@example
|
||||
zcat guile-@value{VERSION}.tar.gz | tar xvf -
|
||||
@end example
|
||||
which will create a directory called @file{guile-@value{VERSION}} with
|
||||
all the sources. You can look at the file @file{INSTALL} for detailed
|
||||
instructions on how to build and install Guile, but you should be able
|
||||
to just do
|
||||
@example
|
||||
cd guile-@value{VERSION}
|
||||
./configure
|
||||
make install
|
||||
@end example
|
||||
|
||||
This will install the Guile executable @file{guile}, the Guile library
|
||||
@file{libguile.a} and various associated header files and support
|
||||
libraries. It will also install the Guile tutorial and reference manual.
|
||||
|
||||
@c [[include instructions for getting R5RS]]
|
||||
|
||||
Since this manual frequently refers to the Scheme ``standard'', also
|
||||
known as R5RS, or the
|
||||
@iftex
|
||||
``Revised$^5$ Report on the Algorithmic Language Scheme'',
|
||||
@end iftex
|
||||
@ifinfo
|
||||
``Revised^5 Report on the Algorithmic Language Scheme'',
|
||||
@end ifinfo
|
||||
we have included the report in the Guile distribution;
|
||||
@xref{Top, , Introduction, r5rs, Revised(5) Report on the Algorithmic
|
||||
Language Scheme}.
|
||||
This will also be installed in your info directory.
|
||||
|
||||
|
||||
@node Packages not shipped with Guile
|
||||
@section Packages not shipped with Guile
|
||||
|
||||
We ship the Guile tutorial and reference manual with the Guile
|
||||
distribution. Since the Scheme standard (R5RS) is a stable document, we
|
||||
ship that too.
|
||||
|
||||
Here are references (usually World Wide Web URLs) to some other freely
|
||||
redistributable documents and packages which you might find useful if
|
||||
you are using Guile.
|
||||
|
||||
@table @strong
|
||||
@item SCSH
|
||||
the Scheme Shell. Gary Houston has ported SCSH to Guile. The relevant
|
||||
chapter (@pxref{The Scheme shell (scsh)}) has references to the SCSH web
|
||||
page with all its documentation.
|
||||
|
||||
@item SLIB
|
||||
a portable Scheme library maintained by Aubrey Jaffer. SLIB can be
|
||||
obtained by ftp from @url{ftp://prep.ai.mit.edu/pub/gnu/jacal/}.
|
||||
|
||||
The SLIB package should be unpacked somewhere in Guile's load path. It
|
||||
will typically be unpacked in @file{/usr/local/share/guile/site}, so
|
||||
that it will be @file{/usr/local/share/guile/site/slib}.
|
||||
|
||||
Guile might have been installed with a different prefix, in which case
|
||||
the load path can be checked from inside the interpreter with:
|
||||
|
||||
@smalllisp
|
||||
guile> %load-path
|
||||
("/usr/local/share/guile/site" "/usr/local/share/guile/1.3a" "/usr/local/share/guile" ".")
|
||||
@end smalllisp
|
||||
|
||||
The relevant chapter (@pxref{SLIB}) has details on how to use SLIB with
|
||||
Guile.
|
||||
|
||||
@item JACAL
|
||||
a symbolic math package by Aubrey Jaffer. The latest version of Jacal
|
||||
can be obtained from @url{ftp://prep.ai.mit.edu/pub/gnu/jacal/}, and
|
||||
should be unpacked in @file{/usr/local/share/guile/site/slib} so that
|
||||
it will be in @file{/usr/local/share/guile/site/slib/jacal}.
|
||||
|
||||
The relevant section (@pxref{JACAL}) has details on how to use Jacal.
|
||||
@end table
|
||||
|
||||
|
||||
@page
|
||||
@node Reporting Bugs
|
||||
@chapter Reporting Bugs
|
||||
|
|
|
@ -263,10 +263,11 @@ a port.
|
|||
|
||||
@deffn {Scheme Procedure} close fd_or_port
|
||||
@deffnx {C Function} scm_close (fd_or_port)
|
||||
Similar to close-port (@pxref{Closing, close-port}), but also works on
|
||||
file descriptors. A side effect of closing a file descriptor is that
|
||||
any ports using that file descriptor are moved to a different file
|
||||
descriptor and have their revealed counts set to zero.
|
||||
Similar to close-port (@pxref{Closing, close-port}),
|
||||
but also works on file descriptors. A side
|
||||
effect of closing a file descriptor is that any ports using that file
|
||||
descriptor are moved to a different file descriptor and have
|
||||
their revealed counts set to zero.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} close-fdes fd
|
||||
|
|
|
@ -6,8 +6,8 @@ This reference manual documents Guile, GNU's Ubiquitous Intelligent
|
|||
Language for Extensions. It describes how to use Guile in many useful
|
||||
and interesting ways.
|
||||
|
||||
This is edition 1.0 of the reference manual, and corresponds to Guile
|
||||
version @value{VERSION}.
|
||||
This is edition @value{MANUAL_EDITION} of the reference manual, and
|
||||
corresponds to Guile version @value{VERSION}.
|
||||
@end iftex
|
||||
|
||||
|
||||
|
@ -93,12 +93,13 @@ organized by functionality rather than by the defining standards.
|
|||
|
||||
@strong{Part III: Guile Modules} describes some important modules,
|
||||
distributed as part of the Guile distribution, that extend the
|
||||
functionality provided by the Guile Scheme core, most notably:
|
||||
functionality provided by the Guile Scheme core. Two important examples
|
||||
are:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
the POSIX module, which provides Scheme level procedures for system and
|
||||
network programming, conforming to the POSIX standard
|
||||
network programming that conform to the POSIX standard
|
||||
|
||||
@item
|
||||
the SLIB module, which makes Aubrey Jaffer's portable Scheme library
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
* Exceptions:: Throwing and catching exceptions.
|
||||
* Error Reporting:: Procedures for signaling errors.
|
||||
* Dynamic Wind:: Guarding against non-local entrance/exit.
|
||||
* Handling Errors:: How to handle errors in C code.
|
||||
@end menu
|
||||
|
||||
|
||||
|
@ -825,6 +826,143 @@ a-cont
|
|||
@result{} special-binding
|
||||
@end lisp
|
||||
@end deffn
|
||||
|
||||
|
||||
@node Handling Errors
|
||||
@section How to Handle Errors in C Code
|
||||
|
||||
Error handling is based on @code{catch} and @code{throw}. Errors are
|
||||
always thrown with a @var{key} and four arguments:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
@var{key}: a symbol which indicates the type of error. The symbols used
|
||||
by libguile are listed below.
|
||||
|
||||
@item
|
||||
@var{subr}: the name of the procedure from which the error is thrown, or
|
||||
@code{#f}.
|
||||
|
||||
@item
|
||||
@var{message}: a string (possibly language and system dependent)
|
||||
describing the error. The tokens @code{~A} and @code{~S} can be
|
||||
embedded within the message: they will be replaced with members of the
|
||||
@var{args} list when the message is printed. @code{~A} indicates an
|
||||
argument printed using @code{display}, while @code{~S} indicates an
|
||||
argument printed using @code{write}. @var{message} can also be
|
||||
@code{#f}, to allow it to be derived from the @var{key} by the error
|
||||
handler (may be useful if the @var{key} is to be thrown from both C and
|
||||
Scheme).
|
||||
|
||||
@item
|
||||
@var{args}: a list of arguments to be used to expand @code{~A} and
|
||||
@code{~S} tokens in @var{message}. Can also be @code{#f} if no
|
||||
arguments are required.
|
||||
|
||||
@item
|
||||
@var{rest}: a list of any additional objects required. e.g., when the
|
||||
key is @code{'system-error}, this contains the C errno value. Can also
|
||||
be @code{#f} if no additional objects are required.
|
||||
@end itemize
|
||||
|
||||
In addition to @code{catch} and @code{throw}, the following Scheme
|
||||
facilities are available:
|
||||
|
||||
@deffn {Scheme Procedure} scm-error key subr message args rest
|
||||
Throw an error, with arguments
|
||||
as described above.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} error msg arg @dots{}
|
||||
Throw an error using the key @code{'misc-error}. The error
|
||||
message is created by displaying @var{msg} and writing the @var{args}.
|
||||
@end deffn
|
||||
|
||||
The following are the error keys defined by libguile and the situations
|
||||
in which they are used:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
@code{error-signal}: thrown after receiving an unhandled fatal signal
|
||||
such as SIGSEGV, SIGBUS, SIGFPE etc. The @var{rest} argument in the throw
|
||||
contains the coded signal number (at present this is not the same as the
|
||||
usual Unix signal number).
|
||||
|
||||
@item
|
||||
@code{system-error}: thrown after the operating system indicates an
|
||||
error condition. The @var{rest} argument in the throw contains the
|
||||
errno value.
|
||||
|
||||
@item
|
||||
@code{numerical-overflow}: numerical overflow.
|
||||
|
||||
@item
|
||||
@code{out-of-range}: the arguments to a procedure do not fall within the
|
||||
accepted domain.
|
||||
|
||||
@item
|
||||
@code{wrong-type-arg}: an argument to a procedure has the wrong type.
|
||||
|
||||
@item
|
||||
@code{wrong-number-of-args}: a procedure was called with the wrong number
|
||||
of arguments.
|
||||
|
||||
@item
|
||||
@code{memory-allocation-error}: memory allocation error.
|
||||
|
||||
@item
|
||||
@code{stack-overflow}: stack overflow error.
|
||||
|
||||
@item
|
||||
@code{regex-error}: errors generated by the regular expression library.
|
||||
|
||||
@item
|
||||
@code{misc-error}: other errors.
|
||||
@end itemize
|
||||
|
||||
|
||||
@subsection C Support
|
||||
|
||||
SCM scm_error (SCM key, char *subr, char *message, SCM args, SCM rest)
|
||||
|
||||
Throws an error, after converting the char * arguments to Scheme strings.
|
||||
subr is the Scheme name of the procedure, NULL is converted to #f.
|
||||
Likewise a NULL message is converted to #f.
|
||||
|
||||
The following procedures invoke scm_error with various error keys and
|
||||
arguments. The first three call scm_error with the system-error key
|
||||
and automatically supply errno in the "rest" argument: scm_syserror
|
||||
generates messages using strerror, scm_sysmissing is used when
|
||||
facilities are not available. Care should be taken that the errno
|
||||
value is not reset (e.g. due to an interrupt).
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
void scm_syserror (char *subr);
|
||||
@item
|
||||
void scm_syserror_msg (char *subr, char *message, SCM args);
|
||||
@item
|
||||
void scm_sysmissing (char *subr);
|
||||
@item
|
||||
void scm_num_overflow (char *subr);
|
||||
@item
|
||||
void scm_out_of_range (char *subr, SCM bad_value);
|
||||
@item
|
||||
void scm_wrong_num_args (SCM proc);
|
||||
@item
|
||||
void scm_wrong_type_arg (char *subr, int pos, SCM bad_value);
|
||||
@item
|
||||
void scm_memory_error (char *subr);
|
||||
@item
|
||||
static void scm_regex_error (char *subr, int code); (only used in rgx.c).
|
||||
@end itemize
|
||||
|
||||
Exception handlers can also be installed from C, using
|
||||
scm_internal_catch, scm_lazy_catch, or scm_stack_catch from
|
||||
libguile/throw.c. These have not yet been documented, however the
|
||||
source contains some useful comments.
|
||||
|
||||
|
||||
@c Local Variables:
|
||||
@c TeX-master: "guile.texi"
|
||||
@c End:
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
@page
|
||||
@node R5RS Index
|
||||
@chapter R5RS Index
|
||||
@unnumbered R5RS Index
|
||||
|
||||
@printindex rn
|
||||
|
||||
|
||||
@page
|
||||
@node Guile Extensions Index
|
||||
@chapter Guile Extensions Index
|
||||
@unnumbered Guile Extensions Index
|
||||
|
||||
@printindex ge
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
* Block Reading and Writing:: Reading and writing blocks of text.
|
||||
* Default Ports:: Defaults for input, output and errors.
|
||||
* Port Types:: Types of port and how to make them.
|
||||
* I/O Extensions:: Using and extending ports in C.
|
||||
@end menu
|
||||
|
||||
|
||||
|
@ -111,7 +112,8 @@ an interactive port will hang waiting for input whenever a call
|
|||
to @code{read-char} would have hung.}
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} unread-char cobj port
|
||||
@deffn {Scheme Procedure} unread-char cobj [port]
|
||||
@deffnx {C Function} scm_unread_char (cobj, port)
|
||||
Place @var{char} in @var{port} so that it will be read by the
|
||||
next read operation. If called multiple times, the unread characters
|
||||
will be read again in last-in first-out order. If @var{port} is
|
||||
|
@ -579,6 +581,8 @@ Return the port to which errors and warnings should be sent (the
|
|||
@deffnx {Scheme Procedure} set-current-output-port port
|
||||
@deffnx {Scheme Procedure} set-current-error-port port
|
||||
@deffnx {C Function} scm_set_current_input_port (port)
|
||||
@deffnx {C Function} scm_set_current_output_port (port)
|
||||
@deffnx {C Function} scm_set_current_error_port (port)
|
||||
Change the ports returned by @code{current-input-port},
|
||||
@code{current-output-port} and @code{current-error-port}, respectively,
|
||||
so that they use the supplied @var{port} for input or output.
|
||||
|
@ -892,6 +896,221 @@ documentation for @code{open-file} in @ref{File Ports}.
|
|||
@end deffn
|
||||
|
||||
|
||||
@node I/O Extensions
|
||||
@section Using and Extending Ports in C
|
||||
|
||||
@menu
|
||||
* C Port Interface:: Using ports from C.
|
||||
* Port Implementation:: How to implement a new port type in C.
|
||||
@end menu
|
||||
|
||||
|
||||
@node C Port Interface
|
||||
@subsection C Port Interface
|
||||
|
||||
This section describes how to use Scheme ports from C.
|
||||
|
||||
@subsubsection Port basics
|
||||
|
||||
There are two main data structures. A port type object (ptob) is of
|
||||
type @code{scm_ptob_descriptor}. A port instance is of type
|
||||
@code{scm_port}. Given an @code{SCM} variable which points to a port,
|
||||
the corresponding C port object can be obtained using the
|
||||
@code{SCM_PTAB_ENTRY} macro. The ptob can be obtained by using
|
||||
@code{SCM_PTOBNUM} to give an index into the @code{scm_ptobs}
|
||||
global array.
|
||||
|
||||
@subsubsection Port buffers
|
||||
|
||||
An input port always has a read buffer and an output port always has a
|
||||
write buffer. However the size of these buffers is not guaranteed to be
|
||||
more than one byte (e.g., the @code{shortbuf} field in @code{scm_port}
|
||||
which is used when no other buffer is allocated). The way in which the
|
||||
buffers are allocated depends on the implementation of the ptob. For
|
||||
example in the case of an fport, buffers may be allocated with malloc
|
||||
when the port is created, but in the case of an strport the underlying
|
||||
string is used as the buffer.
|
||||
|
||||
@subsubsection The @code{rw_random} flag
|
||||
|
||||
Special treatment is required for ports which can be seeked at random.
|
||||
Before various operations, such as seeking the port or changing from
|
||||
input to output on a bidirectional port or vice versa, the port
|
||||
implementation must be given a chance to update its state. The write
|
||||
buffer is updated by calling the @code{flush} ptob procedure and the
|
||||
input buffer is updated by calling the @code{end_input} ptob procedure.
|
||||
In the case of an fport, @code{flush} causes buffered output to be
|
||||
written to the file descriptor, while @code{end_input} causes the
|
||||
descriptor position to be adjusted to account for buffered input which
|
||||
was never read.
|
||||
|
||||
The special treatment must be performed if the @code{rw_random} flag in
|
||||
the port is non-zero.
|
||||
|
||||
@subsubsection The @code{rw_active} variable
|
||||
|
||||
The @code{rw_active} variable in the port is only used if
|
||||
@code{rw_random} is set. It's defined as an enum with the following
|
||||
values:
|
||||
|
||||
@table @code
|
||||
@item SCM_PORT_READ
|
||||
the read buffer may have unread data.
|
||||
|
||||
@item SCM_PORT_WRITE
|
||||
the write buffer may have unwritten data.
|
||||
|
||||
@item SCM_PORT_NEITHER
|
||||
neither the write nor the read buffer has data.
|
||||
@end table
|
||||
|
||||
@subsubsection Reading from a port.
|
||||
|
||||
To read from a port, it's possible to either call existing libguile
|
||||
procedures such as @code{scm_getc} and @code{scm_read_line} or to read
|
||||
data from the read buffer directly. Reading from the buffer involves
|
||||
the following steps:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Flush output on the port, if @code{rw_active} is @code{SCM_PORT_WRITE}.
|
||||
|
||||
@item
|
||||
Fill the read buffer, if it's empty, using @code{scm_fill_input}.
|
||||
|
||||
@item Read the data from the buffer and update the read position in
|
||||
the buffer. Steps 2) and 3) may be repeated as many times as required.
|
||||
|
||||
@item Set rw_active to @code{SCM_PORT_READ} if @code{rw_random} is set.
|
||||
|
||||
@item update the port's line and column counts.
|
||||
@end enumerate
|
||||
|
||||
@subsubsection Writing to a port.
|
||||
|
||||
To write data to a port, calling @code{scm_lfwrite} should be sufficient for
|
||||
most purposes. This takes care of the following steps:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
End input on the port, if @code{rw_active} is @code{SCM_PORT_READ}.
|
||||
|
||||
@item
|
||||
Pass the data to the ptob implementation using the @code{write} ptob
|
||||
procedure. The advantage of using the ptob @code{write} instead of
|
||||
manipulating the write buffer directly is that it allows the data to be
|
||||
written in one operation even if the port is using the single-byte
|
||||
@code{shortbuf}.
|
||||
|
||||
@item
|
||||
Set @code{rw_active} to @code{SCM_PORT_WRITE} if @code{rw_random}
|
||||
is set.
|
||||
@end enumerate
|
||||
|
||||
|
||||
@node Port Implementation
|
||||
@subsection Port Implementation
|
||||
|
||||
This section describes how to implement a new port type in C.
|
||||
|
||||
As described in the previous section, a port type object (ptob) is
|
||||
a structure of type @code{scm_ptob_descriptor}. A ptob is created by
|
||||
calling @code{scm_make_port_type}.
|
||||
|
||||
All of the elements of the ptob, apart from @code{name}, are procedures
|
||||
which collectively implement the port behaviour. Creating a new port
|
||||
type mostly involves writing these procedures.
|
||||
|
||||
@code{scm_make_port_type} initializes three elements of the structure
|
||||
(@code{name}, @code{fill_input} and @code{write}) from its arguments.
|
||||
The remaining elements are initialized with default values and can be
|
||||
set later if required.
|
||||
|
||||
@table @code
|
||||
@item name
|
||||
A pointer to a NUL terminated string: the name of the port type. This
|
||||
is the only element of @code{scm_ptob_descriptor} which is not
|
||||
a procedure. Set via the first argument to @code{scm_make_port_type}.
|
||||
|
||||
@item mark
|
||||
Called during garbage collection to mark any SCM objects that a port
|
||||
object may contain. It doesn't need to be set unless the port has
|
||||
@code{SCM} components. Set using @code{scm_set_port_mark}.
|
||||
|
||||
@item free
|
||||
Called when the port is collected during gc. It
|
||||
should free any resources used by the port.
|
||||
Set using @code{scm_set_port_free}.
|
||||
|
||||
@item print
|
||||
Called when @code{write} is called on the port object, to print a
|
||||
port description. e.g., for an fport it may produce something like:
|
||||
@code{#<input: /etc/passwd 3>}. Set using @code{scm_set_port_print}.
|
||||
|
||||
@item equalp
|
||||
Not used at present. Set using @code{scm_set_port_equalp}.
|
||||
|
||||
@item close
|
||||
Called when the port is closed, unless it was collected during gc. It
|
||||
should free any resources used by the port.
|
||||
Set using @code{scm_set_port_close}.
|
||||
|
||||
@item write
|
||||
Accept data which is to be written using the port. The port implementation
|
||||
may choose to buffer the data instead of processing it directly.
|
||||
Set via the third argument to @code{scm_make_port_type}.
|
||||
|
||||
@item flush
|
||||
Complete the processing of buffered output data. Reset the value of
|
||||
@code{rw_active} to @code{SCM_PORT_NEITHER}.
|
||||
Set using @code{scm_set_port_flush}.
|
||||
|
||||
@item end_input
|
||||
Perform any synchronization required when switching from input to output
|
||||
on the port. Reset the value of @code{rw_active} to @code{SCM_PORT_NEITHER}.
|
||||
Set using @code{scm_set_port_end_input}.
|
||||
|
||||
@item fill_input
|
||||
Read new data into the read buffer and return the first character. It
|
||||
can be assumed that the read buffer is empty when this procedure is called.
|
||||
Set via the second argument to @code{scm_make_port_type}.
|
||||
|
||||
@item input_waiting
|
||||
Return a lower bound on the number of bytes that could be read from the
|
||||
port without blocking. It can be assumed that the current state of
|
||||
@code{rw_active} is @code{SCM_PORT_NEITHER}.
|
||||
Set using @code{scm_set_port_input_waiting}.
|
||||
|
||||
@item seek
|
||||
Set the current position of the port. The procedure can not make
|
||||
any assumptions about the value of @code{rw_active} when it's
|
||||
called. It can reset the buffers first if desired by using something
|
||||
like:
|
||||
|
||||
@example
|
||||
if (pt->rw_active == SCM_PORT_READ)
|
||||
scm_end_input (object);
|
||||
else if (pt->rw_active == SCM_PORT_WRITE)
|
||||
ptob->flush (object);
|
||||
@end example
|
||||
|
||||
However note that this will have the side effect of discarding any data
|
||||
in the unread-char buffer, in addition to any side effects from the
|
||||
@code{end_input} and @code{flush} ptob procedures. This is undesirable
|
||||
when seek is called to measure the current position of the port, i.e.,
|
||||
@code{(seek p 0 SEEK_CUR)}. The libguile fport and string port
|
||||
implementations take care to avoid this problem.
|
||||
|
||||
The procedure is set using @code{scm_set_port_seek}.
|
||||
|
||||
@item truncate
|
||||
Truncate the port data to be specified length. It can be assumed that the
|
||||
current state of @code{rw_active} is @code{SCM_PORT_NEITHER}.
|
||||
Set using @code{scm_set_port_truncate}.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
@c Local Variables:
|
||||
@c TeX-master: "guile.texi"
|
||||
@c End:
|
||||
|
|
|
@ -496,7 +496,7 @@ complete control over which library is loaded when and what gets done
|
|||
with it.
|
||||
|
||||
@deffn {Scheme Procedure} dynamic-link library
|
||||
@deffnx {C Function} scm_dynamic_link (filename)
|
||||
@deffnx {C Function} scm_dynamic_link (library)
|
||||
Find the shared library denoted by @var{library} (a string) and link it
|
||||
into the running Guile application. When everything works out, return a
|
||||
Scheme object suitable for representing the linked object file.
|
||||
|
@ -508,27 +508,26 @@ that will be searched for in the places where shared libraries usually
|
|||
reside, such as in @file{/usr/lib} and @file{/usr/local/lib}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} dynamic-object? val
|
||||
@deffn {Scheme Procedure} dynamic-object? obj
|
||||
@deffnx {C Function} scm_dynamic_object_p (obj)
|
||||
Determine whether @var{val} represents a dynamically linked object file.
|
||||
Return @code{#t} if @var{obj} is a dynamic library handle, or @code{#f}
|
||||
otherwise.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} dynamic-unlink dynobj
|
||||
@deffnx {C Function} scm_dynamic_unlink (dynobj)
|
||||
Unlink the indicated object file from the application. The argument
|
||||
@var{dynobj} should be one of the values returned by
|
||||
@code{dynamic-link}. When @code{dynamic-unlink} has been called on
|
||||
@var{dynobj}, it is no longer usable as an argument to the functions
|
||||
below and you will get type mismatch errors when you try to.
|
||||
@deffn {Scheme Procedure} dynamic-unlink dobj
|
||||
@deffnx {C Function} scm_dynamic_unlink (dobj)
|
||||
Unlink the indicated object file from the application. The
|
||||
argument @var{dobj} must have been obtained by a call to
|
||||
@code{dynamic-link}. After @code{dynamic-unlink} has been
|
||||
called on @var{dobj}, its content is no longer accessible.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} dynamic-func function dynobj
|
||||
@deffnx {C Function} scm_dynamic_func (name, dynobj)
|
||||
Search the C function indicated by @var{function} (a string or symbol)
|
||||
in @var{dynobj} and return some Scheme object that can later be used
|
||||
with @code{dynamic-call} to actually call this function. Right now,
|
||||
these Scheme objects are formed by casting the address of the function
|
||||
to @code{long} and converting this number to its Scheme representation.
|
||||
@deffn {Scheme Procedure} dynamic-func name dobj
|
||||
@deffnx {C Function} scm_dynamic_func (name, dobj)
|
||||
Search the dynamic object @var{dobj} for the C function
|
||||
indicated by the string @var{name} and return some Scheme
|
||||
handle that can later be used with @code{dynamic-call} to
|
||||
actually call the function.
|
||||
|
||||
Regardless whether your C compiler prepends an underscore @samp{_} to
|
||||
the global names in a program, you should @strong{not} include this
|
||||
|
@ -536,37 +535,37 @@ underscore in @var{function}. Guile knows whether the underscore is
|
|||
needed or not and will add it when necessary.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} dynamic-call function dynobj
|
||||
@deffnx {C Function} scm_dynamic_call (func, dynobj)
|
||||
Call the C function indicated by @var{function} and @var{dynobj}. The
|
||||
function is passed no arguments and its return value is ignored. When
|
||||
@var{function} is something returned by @code{dynamic-func}, call that
|
||||
function and ignore @var{dynobj}. When @var{function} is a string (or
|
||||
symbol, etc.), look it up in @var{dynobj}; this is equivalent to
|
||||
|
||||
@deffn {Scheme Procedure} dynamic-call func dobj
|
||||
@deffnx {C Function} scm_dynamic_call (func, dobj)
|
||||
Call the C function indicated by @var{func} and @var{dobj}.
|
||||
The function is passed no arguments and its return value is
|
||||
ignored. When @var{function} is something returned by
|
||||
@code{dynamic-func}, call that function and ignore @var{dobj}.
|
||||
When @var{func} is a string , look it up in @var{dynobj}; this
|
||||
is equivalent to
|
||||
@smallexample
|
||||
(dynamic-call (dynamic-func @var{function} @var{dynobj} #f))
|
||||
(dynamic-call (dynamic-func @var{func} @var{dobj} #f))
|
||||
@end smallexample
|
||||
|
||||
Interrupts are deferred while the C function is executing (with
|
||||
@code{SCM_DEFER_INTS}/@code{SCM_ALLOW_INTS}).
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} dynamic-args-call function dynobj args
|
||||
@deffnx {C Function} scm_dynamic_args_call (function, dynobj, args)
|
||||
Call the C function indicated by @var{function} and @var{dynobj}, just
|
||||
like @code{dynamic-call}, but pass it some arguments and return its
|
||||
return value. The C function is expected to take two arguments and
|
||||
return an @code{int}, just like @code{main}:
|
||||
|
||||
@deffn {Scheme Procedure} dynamic-args-call func dobj args
|
||||
@deffnx {C Function} scm_dynamic_args_call (func, dobj, args)
|
||||
Call the C function indicated by @var{func} and @var{dobj},
|
||||
just like @code{dynamic-call}, but pass it some arguments and
|
||||
return its return value. The C function is expected to take
|
||||
two arguments and return an @code{int}, just like @code{main}:
|
||||
@smallexample
|
||||
int c_func (int argc, char **argv);
|
||||
@end smallexample
|
||||
|
||||
The parameter @var{args} must be a list of strings and is converted into
|
||||
an array of @code{char *}. The array is passed in @var{argv} and its
|
||||
size in @var{argc}. The return value is converted to a Scheme number
|
||||
and returned from the call to @code{dynamic-args-call}.
|
||||
The parameter @var{args} must be a list of strings and is
|
||||
converted into an array of @code{char *}. The array is passed
|
||||
in @var{argv} and its size in @var{argc}. The return value is
|
||||
converted to a Scheme number and returned from the call to
|
||||
@code{dynamic-args-call}.
|
||||
@end deffn
|
||||
|
||||
When dynamic linking is disabled or not supported on your system,
|
||||
|
|
|
@ -23,6 +23,7 @@ configure @emph{reading}, @emph{printing}, @emph{debugging} or
|
|||
* Evaluator trap options::
|
||||
* Examples of option use::
|
||||
* Install Config:: Installation and configuration data.
|
||||
* Feature Tracking:: Available features in the Guile process.
|
||||
@end menu
|
||||
|
||||
@node General option interface
|
||||
|
@ -402,6 +403,214 @@ List of directories which should be searched for Scheme
|
|||
modules and libraries.
|
||||
@end defvar
|
||||
|
||||
@defvar %guile-build-info
|
||||
Alist of information collected during the building of a particular
|
||||
@code{guile} program. Entries can be grouped into one of several
|
||||
categories: directories, env vars, and versioning info.
|
||||
|
||||
Briefly, here are the keys in @code{%guile-build-info}, by group:
|
||||
@itemize @bullet
|
||||
@item directories
|
||||
srcdir, top_srcdir, prefix, exec_prefix, bindir, sbindir, libexecdir,
|
||||
datadir, sysconfdir, sharedstatedir, localstatedir, libdir, infodir,
|
||||
mandir, includedir, pkgdatadir, pkglibdir, pkgincludedir
|
||||
@item env vars
|
||||
LIBS
|
||||
@item versioning info
|
||||
guileversion, libguileinterface, buildstamp
|
||||
@end itemize
|
||||
|
||||
Values are all strings. The value for @code{LIBS} is typically found also as
|
||||
a part of "guile-config link" output. The value for @code{guileversion} has
|
||||
form X.Y.Z, and should be the same as returned by @code{version}. The value
|
||||
for @code{libguileinterface} is libtool compatible and has form
|
||||
CURRENT:REVISION:AGE. The value for @code{buildstamp} is the output of the
|
||||
date(1) command.
|
||||
|
||||
In the source, @code{%guile-build-info} is initialized from
|
||||
libguile/libpath.h, which is completely generated, so deleting this file
|
||||
before a build guarantees up-to-date values for that build.
|
||||
@end defvar
|
||||
|
||||
|
||||
@node Feature Tracking
|
||||
@section Feature Tracking
|
||||
|
||||
Guile has a Scheme level variable @code{*features*} that keeps track to
|
||||
some extent of the features that are available in a running Guile.
|
||||
@code{*features*} is a list of symbols, for example @code{threads}, each
|
||||
of which describes a feature of the running Guile process.
|
||||
|
||||
@defvar *features*
|
||||
A list of symbols describing available features of the Guile process.
|
||||
@end defvar
|
||||
|
||||
You shouldn't modify the @code{*features*} variable directly using
|
||||
@code{set!}. Instead, see the procedures that are provided for this
|
||||
purpose in the following subsection.
|
||||
|
||||
@menu
|
||||
* Feature Manipulation:: Checking for and advertising features.
|
||||
* Common Feature Symbols:: Commonly available features.
|
||||
@end menu
|
||||
|
||||
|
||||
@node Feature Manipulation
|
||||
@subsection Feature Manipulation
|
||||
|
||||
To check whether a particular feature is available, use the
|
||||
@code{provided?} procedure:
|
||||
|
||||
@deffn {Scheme Procedure} provided? feature
|
||||
@deffnx {Deprecated Scheme Procedure} feature? feature
|
||||
Return @code{#t} if the specified @var{feature} is available, otherwise
|
||||
@code{#f}.
|
||||
@end deffn
|
||||
|
||||
To advertise a feature from your own Scheme code, you can use the
|
||||
@code{provide} procedure:
|
||||
|
||||
@deffn {Scheme Procedure} provide feature
|
||||
Add @var{feature} to the list of available features in this Guile
|
||||
process.
|
||||
@end deffn
|
||||
|
||||
For C code, the equivalent function takes its feature name as a
|
||||
@code{char *} argument for convenience:
|
||||
|
||||
@deftypefn {C Function} void scm_add_feature (const char *str)
|
||||
Add a symbol with name @var{str} to the list of available features in
|
||||
this Guile process.
|
||||
@end deftypefn
|
||||
|
||||
|
||||
@node Common Feature Symbols
|
||||
@subsection Common Feature Symbols
|
||||
|
||||
In general, a particular feature may be available for one of two
|
||||
reasons. Either because the Guile library was configured and compiled
|
||||
with that feature enabled --- i.e. the feature is built into the library
|
||||
on your system. Or because some C or Scheme code that was dynamically
|
||||
loaded by Guile has added that feature to the list.
|
||||
|
||||
In the first category, here are the features that the current version of
|
||||
Guile may define (depending on how it is built), and what they mean.
|
||||
|
||||
@table @code
|
||||
@item array
|
||||
Indicates support for arrays (@pxref{Arrays}).
|
||||
|
||||
@item array-for-each
|
||||
Indicates availability of @code{array-for-each} and other array mapping
|
||||
procedures (@pxref{Array Mapping}).
|
||||
|
||||
@item char-ready?
|
||||
Indicates that the @code{char-ready?} function is available
|
||||
(@pxref{Reading}).
|
||||
|
||||
@item complex
|
||||
Indicates support for complex numbers.
|
||||
|
||||
@item current-time
|
||||
Indicates availability of time-related functions: @code{times},
|
||||
@code{get-internal-run-time} and so on (@pxref{Time}).
|
||||
|
||||
@item debug-extensions
|
||||
Indicates that the debugging evaluator is available, together with the
|
||||
options for controlling it.
|
||||
|
||||
@item delay
|
||||
Indicates support for promises (@pxref{Delayed Evaluation}).
|
||||
|
||||
@item EIDs
|
||||
Indicates that the @code{geteuid} and @code{getegid} really return
|
||||
effective user and group IDs (@pxref{Processes}).
|
||||
|
||||
@item inexact
|
||||
Indicates support for inexact numbers.
|
||||
|
||||
@item i/o-extensions
|
||||
Indicates availability of the following extended I/O procedures:
|
||||
@code{ftell}, @code{redirect-port}, @code{dup->fdes}, @code{dup2},
|
||||
@code{fileno}, @code{isatty?}, @code{fdopen},
|
||||
@code{primitive-move->fdes} and @code{fdes->ports} (@pxref{Ports and
|
||||
File Descriptors}).
|
||||
|
||||
@item net-db
|
||||
Indicates availability of network database functions:
|
||||
@code{scm_gethost}, @code{scm_getnet}, @code{scm_getproto},
|
||||
@code{scm_getserv}, @code{scm_sethost}, @code{scm_setnet}, @code{scm_setproto},
|
||||
@code{scm_setserv}, and their `byXXX' variants (@pxref{Network
|
||||
Databases}).
|
||||
|
||||
@item posix
|
||||
Indicates support for POSIX functions: @code{pipe}, @code{getgroups},
|
||||
@code{kill}, @code{execl} and so on (@pxref{POSIX}).
|
||||
|
||||
@item random
|
||||
Indicates availability of random number generation functions:
|
||||
@code{random}, @code{copy-random-state}, @code{random-uniform} and so on
|
||||
(@pxref{Random}).
|
||||
|
||||
@item reckless
|
||||
Indicates that Guile was built with important checks omitted --- you
|
||||
should never see this!
|
||||
|
||||
@item regex
|
||||
Indicates support for POSIX regular expressions using
|
||||
@code{make-regexp}, @code{regexp-exec} and friends (@pxref{Regexp
|
||||
Functions}).
|
||||
|
||||
@item socket
|
||||
Indicates availability of socket-related functions: @code{socket},
|
||||
@code{bind}, @code{connect} and so on (@pxref{Network Sockets and
|
||||
Communication}).
|
||||
|
||||
@item sort
|
||||
Indicates availability of sorting and merging functions
|
||||
(@pxref{Sorting}).
|
||||
|
||||
@item system
|
||||
Indicates that the @code{system} function is available
|
||||
(@pxref{Processes}).
|
||||
|
||||
@item threads
|
||||
Indicates support for multithreading (@pxref{Threads}).
|
||||
|
||||
@item values
|
||||
Indicates support for multiple return values using @code{values} and
|
||||
@code{call-with-values} (@pxref{Multiple Values}).
|
||||
@end table
|
||||
|
||||
Available features in the second category depend, by definition, on what
|
||||
additional code your Guile process has loaded in. The following table
|
||||
lists features that you might encounter for this reason.
|
||||
|
||||
@table @code
|
||||
@item defmacro
|
||||
Indicates that the @code{defmacro} macro is available (@pxref{Macros}).
|
||||
|
||||
@item describe
|
||||
Indicates that the @code{(oop goops describe)} module has been loaded,
|
||||
which provides a procedure for describing the contents of GOOPS
|
||||
instances.
|
||||
|
||||
@item readline
|
||||
Indicates that Guile has loaded in Readline support, for command line
|
||||
editing (@pxref{Readline Support}).
|
||||
|
||||
@item record
|
||||
Indicates support for record definition using @code{make-record-type}
|
||||
and friends (@pxref{Records}).
|
||||
@end table
|
||||
|
||||
Although these tables may seem exhaustive, it is probably unwise in
|
||||
practice to rely on them, as the correspondences between feature symbols
|
||||
and available procedures/behaviour are not strictly defined. If you are
|
||||
writing code that needs to check for the existence of some procedure, it
|
||||
is probably safer to do so directly using the @code{defined?} procedure
|
||||
than to test for the corresponding feature using @code{feature?}.
|
||||
|
||||
|
||||
@c Local Variables:
|
||||
@c TeX-master: "guile.texi"
|
||||
|
|
|
@ -377,24 +377,38 @@ argument @var{printer} (default: @code{write}).
|
|||
@section Hooks
|
||||
@tpindex Hooks
|
||||
|
||||
@c FIXME::martin: Review me!
|
||||
A hook is a list of procedures to be called at well defined points in
|
||||
time. Typically, an application provides a hook @var{h} and promises
|
||||
its users that it will call all of the procedures in @var{h} at a
|
||||
defined point in the application's processing. By adding its own
|
||||
procedure to @var{h}, an application user can tap into or even influence
|
||||
the progress of the application.
|
||||
|
||||
A hook is basically a list of procedures to be called at well defined
|
||||
points in time. Hooks are used internally for several debugging
|
||||
facilities, but they can be used in user code, too.
|
||||
Guile itself provides several such hooks for debugging and customization
|
||||
purposes: these are listed in a subsection below.
|
||||
|
||||
Hooks are created with @code{make-hook}, then procedures can be added to
|
||||
a hook with @code{add-hook!} or removed with @code{remove-hook!} or
|
||||
@code{reset-hook!}. The procedures stored in a hook can be invoked with
|
||||
@code{run-hook}.
|
||||
When an application first creates a hook, it needs to know how many
|
||||
arguments will be passed to the hook's procedures when the hook is run.
|
||||
The chosen number of arguments (which may be none) is declared when the
|
||||
hook is created, and all the procedures that are added to that hook must
|
||||
be capable of accepting that number of arguments.
|
||||
|
||||
A hook is created using @code{make-hook}. A procedure can be added to
|
||||
or removed from a hook using @code{add-hook!} or @code{remove-hook!},
|
||||
and all of a hook's procedures can be removed together using
|
||||
@code{reset-hook!}. When an application wants to run a hook, it does so
|
||||
using @code{run-hook}.
|
||||
|
||||
@menu
|
||||
* Hook Examples:: Hook usage by example.
|
||||
* Hook Example:: Hook usage by example.
|
||||
* Hook Reference:: Reference of all hook procedures.
|
||||
* C Hooks:: Hooks for use from C code.
|
||||
* Guile Hooks:: Hooks provided by Guile.
|
||||
@end menu
|
||||
|
||||
@node Hook Examples
|
||||
@subsection Hook Examples
|
||||
|
||||
@node Hook Example
|
||||
@subsection Hook Usage by Example
|
||||
|
||||
Hook usage is shown by some examples in this section. First, we will
|
||||
define a hook of arity 2 --- that is, the procedures stored in the hook
|
||||
|
@ -409,8 +423,7 @@ hook
|
|||
Now we are ready to add some procedures to the newly created hook with
|
||||
@code{add-hook!}. In the following example, two procedures are added,
|
||||
which print different messages and do different things with their
|
||||
arguments. When the procedures have been added, we can invoke them
|
||||
using @code{run-hook}.
|
||||
arguments.
|
||||
|
||||
@lisp
|
||||
(add-hook! hook (lambda (x y)
|
||||
|
@ -421,14 +434,23 @@ using @code{run-hook}.
|
|||
(display "Bar: ")
|
||||
(display (* x y))
|
||||
(newline)))
|
||||
@end lisp
|
||||
|
||||
Once the procedures have been added, we can invoke the hook using
|
||||
@code{run-hook}.
|
||||
|
||||
@lisp
|
||||
(run-hook hook 3 4)
|
||||
@print{} Bar: 12
|
||||
@print{} Foo: 7
|
||||
@end lisp
|
||||
|
||||
Note that the procedures are called in reverse order than they were
|
||||
added. This can be changed by providing the optional third argument
|
||||
on the second call to @code{add-hook!}.
|
||||
Note that the procedures are called in the reverse of the order with
|
||||
which they were added. This is because the default behaviour of
|
||||
@code{add-hook!} is to add its procedure to the @emph{front} of the
|
||||
hook's procedure list. You can force @code{add-hook!} to add its
|
||||
procedure to the @emph{end} of the list instead by providing a third
|
||||
@code{#t} argument on the second call to @code{add-hook!}.
|
||||
|
||||
@lisp
|
||||
(add-hook! hook (lambda (x y)
|
||||
|
@ -439,30 +461,34 @@ on the second call to @code{add-hook!}.
|
|||
(display "Bar: ")
|
||||
(display (* x y))
|
||||
(newline))
|
||||
#t) ; @r{<- Change here!}
|
||||
#t) ; @r{<- Change here!}
|
||||
|
||||
(run-hook hook 3 4)
|
||||
@print{} Foo: 7
|
||||
@print{} Bar: 12
|
||||
@end lisp
|
||||
|
||||
|
||||
@node Hook Reference
|
||||
@subsection Hook Reference
|
||||
|
||||
When a hook is created with @code{make-hook}, you can supply the arity
|
||||
of the procedures which can be added to the hook. The arity defaults to
|
||||
zero. All procedures of a hook must have the same arity, and when the
|
||||
procedures are invoked using @code{run-hook}, the number of arguments
|
||||
must match the arity of the procedures.
|
||||
When you create a hook with @code{make-hook}, you must specify the arity
|
||||
of the procedures which can be added to the hook. If the arity is not
|
||||
given explicitly as an argument to @code{make-hook}, it defaults to
|
||||
zero. All procedures of a given hook must have the same arity, and when
|
||||
the procedures are invoked using @code{run-hook}, the number of
|
||||
arguments passed must match the arity specified at hook creation time.
|
||||
|
||||
The order in which procedures are added to a hook matters. If the third
|
||||
parameter to @var{add-hook!} is omitted or is equal to @code{#f}, the
|
||||
parameter to @code{add-hook!} is omitted or is equal to @code{#f}, the
|
||||
procedure is added in front of the procedures which might already be on
|
||||
that hook, otherwise the procedure is added at the end. The procedures
|
||||
are always called from first to last when they are invoked via
|
||||
@code{run-hook}.
|
||||
are always called from the front to the end of the list when they are
|
||||
invoked via @code{run-hook}.
|
||||
|
||||
When calling @code{hook->list}, the procedures in the resulting list are
|
||||
in the same order as they would have been called by @code{run-hook}.
|
||||
The ordering of the list of procedures returned by @code{hook->list}
|
||||
matches the order in which those procedures would be called if the hook
|
||||
was run using @code{run-hook}.
|
||||
|
||||
@deffn {Scheme Procedure} make-hook [n_args]
|
||||
@deffnx {C Function} scm_make_hook (n_args)
|
||||
|
@ -502,6 +528,11 @@ Remove all procedures from the hook @var{hook}. The return
|
|||
value of this procedure is not specified.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} hook->list hook
|
||||
@deffnx {C Function} scm_hook_to_list (hook)
|
||||
Convert the procedure list of @var{hook} to a list.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} run-hook hook . args
|
||||
@deffnx {C Function} scm_run_hook (hook, args)
|
||||
Apply all procedures from the hook @var{hook} to the arguments
|
||||
|
@ -509,10 +540,190 @@ Apply all procedures from the hook @var{hook} to the arguments
|
|||
last. The return value of this procedure is not specified.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} hook->list hook
|
||||
@deffnx {C Function} scm_hook_to_list (hook)
|
||||
Convert the procedure list of @var{hook} to a list.
|
||||
@end deffn
|
||||
If, in C code, you are certain that you have a hook object and well
|
||||
formed argument list for that hook, you can also use
|
||||
@code{scm_c_run_hook}, which is identical to @code{scm_run_hook} but
|
||||
does no type checking.
|
||||
|
||||
@deftypefn {C Function} void scm_c_run_hook (SCM hook, SCM args)
|
||||
The same as @code{scm_run_hook} but without any type checking to confirm
|
||||
that @var{hook} is actually a hook object and that @var{args} is a
|
||||
well-formed list matching the arity of the hook.
|
||||
@end deftypefn
|
||||
|
||||
|
||||
@node C Hooks
|
||||
@subsection Hooks For C Code.
|
||||
|
||||
The hooks already described are intended to be populated by Scheme-level
|
||||
procedures. In addition to this, the Guile library provides an
|
||||
independent set of interfaces for the creation and manipulation of hooks
|
||||
that are designed to be populated by functions implemented in C.
|
||||
|
||||
The original motivation here was to provide a kind of hook that could
|
||||
safely be invoked at various points during garbage collection.
|
||||
Scheme-level hooks are unsuitable for this purpose as running them could
|
||||
itself require memory allocation, which would then invoke garbage
|
||||
collection recursively @dots{} However, it is also the case that these
|
||||
hooks are easier to work with than the Scheme-level ones if you only
|
||||
want to register C functions with them. So if that is mainly what your
|
||||
code needs to do, you may prefer to use this interface.
|
||||
|
||||
To create a C hook, you should allocate storage for a structure of type
|
||||
@code{scm_t_c_hook} and then initialize it using @code{scm_c_hook_init}.
|
||||
|
||||
@deftp {C Type} scm_t_c_hook
|
||||
Data type for a C hook. The internals of this type should be treated as
|
||||
opaque.
|
||||
@end deftp
|
||||
|
||||
@deftp {C Enum} scm_t_c_hook_type
|
||||
Enumeration of possible hook types, which are:
|
||||
|
||||
@table @code
|
||||
@item SCM_C_HOOK_NORMAL
|
||||
@vindex SCM_C_HOOK_NORMAL
|
||||
Type of hook for which all the registered functions will always be called.
|
||||
@item SCM_C_HOOK_OR
|
||||
@vindex SCM_C_HOOK_OR
|
||||
Type of hook for which the sequence of registered functions will be
|
||||
called only until one of them returns C true (a non-NULL pointer).
|
||||
@item SCM_C_HOOK_AND
|
||||
@vindex SCM_C_HOOK_AND
|
||||
Type of hook for which the sequence of registered functions will be
|
||||
called only until one of them returns C false (a NULL pointer).
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
@deftypefn {C Function} void scm_c_hook_init (scm_t_c_hook *hook, void *hook_data, scm_t_c_hook_type type)
|
||||
Initialize the C hook at memory pointed to by @var{hook}. @var{type}
|
||||
should be one of the values of the @code{scm_t_c_hook_type} enumeration,
|
||||
and controls how the hook functions will be called. @var{hook_data} is
|
||||
a closure parameter that will be passed to all registered hook functions
|
||||
when they are called.
|
||||
@end deftypefn
|
||||
|
||||
To add or remove a C function from a C hook, use @code{scm_c_hook_add}
|
||||
or @code{scm_c_hook_remove}. A hook function must expect three
|
||||
@code{void *} parameters which are, respectively:
|
||||
|
||||
@table @var
|
||||
@item hook_data
|
||||
The hook closure data that was specified at the time the hook was
|
||||
initialized by @code{scm_c_hook_init}.
|
||||
|
||||
@item func_data
|
||||
The function closure data that was specified at the time that that
|
||||
function was registered with the hook by @code{scm_c_hook_add}.
|
||||
|
||||
@item data
|
||||
The call closure data specified by the @code{scm_c_hook_run} call that
|
||||
runs the hook.
|
||||
@end table
|
||||
|
||||
@deftp {C Type} scm_t_c_hook_function
|
||||
Function type for a C hook function: takes three @code{void *}
|
||||
parameters and returns a @code{void *} result.
|
||||
@end deftp
|
||||
|
||||
@deftypefn {C Function} void scm_c_hook_add (scm_t_c_hook *hook, scm_t_c_hook_function func, void *func_data, int appendp)
|
||||
Add function @var{func}, with function closure data @var{func_data}, to
|
||||
the C hook @var{hook}. The new function is appended to the hook's list
|
||||
of functions if @var{appendp} is non-zero, otherwise prepended.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {C Function} void scm_c_hook_remove (scm_t_c_hook *hook, scm_t_c_hook_function func, void *func_data)
|
||||
Remove function @var{func}, with function closure data @var{func_data},
|
||||
from the C hook @var{hook}. @code{scm_c_hook_remove} checks both
|
||||
@var{func} and @var{func_data} so as to allow for the same @var{func}
|
||||
being registered multiple times with different closure data.
|
||||
@end deftypefn
|
||||
|
||||
Finally, to invoke a C hook, call the @code{scm_c_hook_run} function
|
||||
specifying the hook and the call closure data for this run:
|
||||
|
||||
@deftypefn {C Function} void * scm_c_hook_run (scm_t_c_hook *hook, void *data)
|
||||
Run the C hook @var{hook} will call closure data @var{data}. Subject to
|
||||
the variations for hook types @code{SCM_C_HOOK_OR} and
|
||||
@code{SCM_C_HOOK_AND}, @code{scm_c_hook_run} calls @var{hook}'s
|
||||
registered functions in turn, passing them the hook's closure data, each
|
||||
function's closure data, and the call closure data.
|
||||
|
||||
@code{scm_c_hook_run}'s return value is the return value of the last
|
||||
function to be called.
|
||||
@end deftypefn
|
||||
|
||||
|
||||
@node Guile Hooks
|
||||
@subsection Hooks Provided by Guile
|
||||
|
||||
@menu
|
||||
* GC Hooks:: Garbage collection hooks.
|
||||
* REPL Hooks:: Hooks into the Guile REPL.
|
||||
@end menu
|
||||
|
||||
|
||||
@node GC Hooks
|
||||
@subsubsection Hooks for Garbage Collection
|
||||
|
||||
Whenever Guile performs a garbage collection, it calls the following
|
||||
hooks in the order shown.
|
||||
|
||||
@defvr {C Hook} scm_before_gc_c_hook
|
||||
C hook called at the very start of a garbage collection, after setting
|
||||
@code{scm_gc_running_p} to 1, but before entering the GC critical
|
||||
section.
|
||||
|
||||
If garbage collection is blocked because @code{scm_block_gc} is
|
||||
non-zero, GC exits early soon after calling this hook, and no further
|
||||
hooks will be called.
|
||||
@end defvr
|
||||
|
||||
@defvr {C Hook} scm_before_mark_c_hook
|
||||
C hook called before beginning the mark phase of garbage collection,
|
||||
after the GC thread has entered a critical section.
|
||||
@end defvr
|
||||
|
||||
@defvr {C Hook} scm_before_sweep_c_hook
|
||||
C hook called before beginning the sweep phase of garbage collection.
|
||||
This is the same as at the end of the mark phase, since nothing else
|
||||
happens between marking and sweeping.
|
||||
@end defvr
|
||||
|
||||
@defvr {C Hook} scm_after_sweep_c_hook
|
||||
C hook called after the end of the sweep phase of garbage collection,
|
||||
but while the GC thread is still inside its critical section.
|
||||
@end defvr
|
||||
|
||||
@defvr {C Hook} scm_after_gc_c_hook
|
||||
C hook called at the very end of a garbage collection, after the GC
|
||||
thread has left its critical section.
|
||||
@end defvr
|
||||
|
||||
@defvr {Scheme Hook} after-gc-hook
|
||||
@vindex scm_after_gc_hook
|
||||
Scheme hook with arity 0. This hook is run asynchronously
|
||||
(@pxref{Asyncs}) soon after the GC has completed and any other events
|
||||
that were deferred during garbage collection have been processed. (Also
|
||||
accessible from C with the name @code{scm_after_gc_hook}.)
|
||||
@end defvr
|
||||
|
||||
All the C hooks listed here have type @code{SCM_C_HOOK_NORMAL}, are
|
||||
initialized with hook closure data NULL, are are invoked by
|
||||
@code{scm_c_hook_run} with call closure data NULL.
|
||||
|
||||
@cindex guardians, testing for GC'd objects
|
||||
The Scheme hook @code{after-gc-hook} is particularly useful in
|
||||
conjunction with guardians (@pxref{Guardians}). Typically, if you are
|
||||
using a guardian, you want to call the guardian after garbage collection
|
||||
to see if any of the objects added to the guardian have been collected.
|
||||
By adding a thunk that performs this call to @code{after-gc-hook}, you
|
||||
can ensure that your guardian is tested after every garbage collection
|
||||
cycle.
|
||||
|
||||
|
||||
@node REPL Hooks
|
||||
@subsubsection Hooks into the Guile REPL
|
||||
|
||||
|
||||
@c Local Variables:
|
||||
|
|
350
doc/ref/scm.texi
350
doc/ref/scm.texi
|
@ -107,354 +107,4 @@ C function's arguments, as well as its return type, will be @code{SCM}.
|
|||
@c There are some exceptions to the regular structure described above.
|
||||
|
||||
|
||||
@page
|
||||
@node I/O Extensions
|
||||
@chapter Using and Extending Ports in C
|
||||
|
||||
@menu
|
||||
* C Port Interface:: Using ports from C.
|
||||
* Port Implementation:: How to implement a new port type in C.
|
||||
@end menu
|
||||
|
||||
|
||||
@node C Port Interface
|
||||
@section C Port Interface
|
||||
|
||||
This section describes how to use Scheme ports from C.
|
||||
|
||||
@subsection Port basics
|
||||
|
||||
There are two main data structures. A port type object (ptob) is of
|
||||
type @code{scm_ptob_descriptor}. A port instance is of type
|
||||
@code{scm_port}. Given an @code{SCM} variable which points to a port,
|
||||
the corresponding C port object can be obtained using the
|
||||
@code{SCM_PTAB_ENTRY} macro. The ptob can be obtained by using
|
||||
@code{SCM_PTOBNUM} to give an index into the @code{scm_ptobs}
|
||||
global array.
|
||||
|
||||
@subsection Port buffers
|
||||
|
||||
An input port always has a read buffer and an output port always has a
|
||||
write buffer. However the size of these buffers is not guaranteed to be
|
||||
more than one byte (e.g., the @code{shortbuf} field in @code{scm_port}
|
||||
which is used when no other buffer is allocated). The way in which the
|
||||
buffers are allocated depends on the implementation of the ptob. For
|
||||
example in the case of an fport, buffers may be allocated with malloc
|
||||
when the port is created, but in the case of an strport the underlying
|
||||
string is used as the buffer.
|
||||
|
||||
@subsection The @code{rw_random} flag
|
||||
|
||||
Special treatment is required for ports which can be seeked at random.
|
||||
Before various operations, such as seeking the port or changing from
|
||||
input to output on a bidirectional port or vice versa, the port
|
||||
implementation must be given a chance to update its state. The write
|
||||
buffer is updated by calling the @code{flush} ptob procedure and the
|
||||
input buffer is updated by calling the @code{end_input} ptob procedure.
|
||||
In the case of an fport, @code{flush} causes buffered output to be
|
||||
written to the file descriptor, while @code{end_input} causes the
|
||||
descriptor position to be adjusted to account for buffered input which
|
||||
was never read.
|
||||
|
||||
The special treatment must be performed if the @code{rw_random} flag in
|
||||
the port is non-zero.
|
||||
|
||||
@subsection The @code{rw_active} variable
|
||||
|
||||
The @code{rw_active} variable in the port is only used if
|
||||
@code{rw_random} is set. It's defined as an enum with the following
|
||||
values:
|
||||
|
||||
@table @code
|
||||
@item SCM_PORT_READ
|
||||
the read buffer may have unread data.
|
||||
|
||||
@item SCM_PORT_WRITE
|
||||
the write buffer may have unwritten data.
|
||||
|
||||
@item SCM_PORT_NEITHER
|
||||
neither the write nor the read buffer has data.
|
||||
@end table
|
||||
|
||||
@subsection Reading from a port.
|
||||
|
||||
To read from a port, it's possible to either call existing libguile
|
||||
procedures such as @code{scm_getc} and @code{scm_read_line} or to read
|
||||
data from the read buffer directly. Reading from the buffer involves
|
||||
the following steps:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Flush output on the port, if @code{rw_active} is @code{SCM_PORT_WRITE}.
|
||||
|
||||
@item
|
||||
Fill the read buffer, if it's empty, using @code{scm_fill_input}.
|
||||
|
||||
@item Read the data from the buffer and update the read position in
|
||||
the buffer. Steps 2) and 3) may be repeated as many times as required.
|
||||
|
||||
@item Set rw_active to @code{SCM_PORT_READ} if @code{rw_random} is set.
|
||||
|
||||
@item update the port's line and column counts.
|
||||
@end enumerate
|
||||
|
||||
@subsection Writing to a port.
|
||||
|
||||
To write data to a port, calling @code{scm_lfwrite} should be sufficient for
|
||||
most purposes. This takes care of the following steps:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
End input on the port, if @code{rw_active} is @code{SCM_PORT_READ}.
|
||||
|
||||
@item
|
||||
Pass the data to the ptob implementation using the @code{write} ptob
|
||||
procedure. The advantage of using the ptob @code{write} instead of
|
||||
manipulating the write buffer directly is that it allows the data to be
|
||||
written in one operation even if the port is using the single-byte
|
||||
@code{shortbuf}.
|
||||
|
||||
@item
|
||||
Set @code{rw_active} to @code{SCM_PORT_WRITE} if @code{rw_random}
|
||||
is set.
|
||||
@end enumerate
|
||||
|
||||
|
||||
@node Port Implementation
|
||||
@section Port Implementation
|
||||
|
||||
This section describes how to implement a new port type in C.
|
||||
|
||||
As described in the previous section, a port type object (ptob) is
|
||||
a structure of type @code{scm_ptob_descriptor}. A ptob is created by
|
||||
calling @code{scm_make_port_type}.
|
||||
|
||||
All of the elements of the ptob, apart from @code{name}, are procedures
|
||||
which collectively implement the port behaviour. Creating a new port
|
||||
type mostly involves writing these procedures.
|
||||
|
||||
@code{scm_make_port_type} initializes three elements of the structure
|
||||
(@code{name}, @code{fill_input} and @code{write}) from its arguments.
|
||||
The remaining elements are initialized with default values and can be
|
||||
set later if required.
|
||||
|
||||
@table @code
|
||||
@item name
|
||||
A pointer to a NUL terminated string: the name of the port type. This
|
||||
is the only element of @code{scm_ptob_descriptor} which is not
|
||||
a procedure. Set via the first argument to @code{scm_make_port_type}.
|
||||
|
||||
@item mark
|
||||
Called during garbage collection to mark any SCM objects that a port
|
||||
object may contain. It doesn't need to be set unless the port has
|
||||
@code{SCM} components. Set using @code{scm_set_port_mark}.
|
||||
|
||||
@item free
|
||||
Called when the port is collected during gc. It
|
||||
should free any resources used by the port.
|
||||
Set using @code{scm_set_port_free}.
|
||||
|
||||
@item print
|
||||
Called when @code{write} is called on the port object, to print a
|
||||
port description. e.g., for an fport it may produce something like:
|
||||
@code{#<input: /etc/passwd 3>}. Set using @code{scm_set_port_print}.
|
||||
|
||||
@item equalp
|
||||
Not used at present. Set using @code{scm_set_port_equalp}.
|
||||
|
||||
@item close
|
||||
Called when the port is closed, unless it was collected during gc. It
|
||||
should free any resources used by the port.
|
||||
Set using @code{scm_set_port_close}.
|
||||
|
||||
@item write
|
||||
Accept data which is to be written using the port. The port implementation
|
||||
may choose to buffer the data instead of processing it directly.
|
||||
Set via the third argument to @code{scm_make_port_type}.
|
||||
|
||||
@item flush
|
||||
Complete the processing of buffered output data. Reset the value of
|
||||
@code{rw_active} to @code{SCM_PORT_NEITHER}.
|
||||
Set using @code{scm_set_port_flush}.
|
||||
|
||||
@item end_input
|
||||
Perform any synchronization required when switching from input to output
|
||||
on the port. Reset the value of @code{rw_active} to @code{SCM_PORT_NEITHER}.
|
||||
Set using @code{scm_set_port_end_input}.
|
||||
|
||||
@item fill_input
|
||||
Read new data into the read buffer and return the first character. It
|
||||
can be assumed that the read buffer is empty when this procedure is called.
|
||||
Set via the second argument to @code{scm_make_port_type}.
|
||||
|
||||
@item input_waiting
|
||||
Return a lower bound on the number of bytes that could be read from the
|
||||
port without blocking. It can be assumed that the current state of
|
||||
@code{rw_active} is @code{SCM_PORT_NEITHER}.
|
||||
Set using @code{scm_set_port_input_waiting}.
|
||||
|
||||
@item seek
|
||||
Set the current position of the port. The procedure can not make
|
||||
any assumptions about the value of @code{rw_active} when it's
|
||||
called. It can reset the buffers first if desired by using something
|
||||
like:
|
||||
|
||||
@example
|
||||
if (pt->rw_active == SCM_PORT_READ)
|
||||
scm_end_input (object);
|
||||
else if (pt->rw_active == SCM_PORT_WRITE)
|
||||
ptob->flush (object);
|
||||
@end example
|
||||
|
||||
However note that this will have the side effect of discarding any data
|
||||
in the unread-char buffer, in addition to any side effects from the
|
||||
@code{end_input} and @code{flush} ptob procedures. This is undesirable
|
||||
when seek is called to measure the current position of the port, i.e.,
|
||||
@code{(seek p 0 SEEK_CUR)}. The libguile fport and string port
|
||||
implementations take care to avoid this problem.
|
||||
|
||||
The procedure is set using @code{scm_set_port_seek}.
|
||||
|
||||
@item truncate
|
||||
Truncate the port data to be specified length. It can be assumed that the
|
||||
current state of @code{rw_active} is @code{SCM_PORT_NEITHER}.
|
||||
Set using @code{scm_set_port_truncate}.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
@node Handling Errors
|
||||
@chapter How to Handle Errors in C Code
|
||||
|
||||
Error handling is based on @code{catch} and @code{throw}. Errors are
|
||||
always thrown with a @var{key} and four arguments:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
@var{key}: a symbol which indicates the type of error. The symbols used
|
||||
by libguile are listed below.
|
||||
|
||||
@item
|
||||
@var{subr}: the name of the procedure from which the error is thrown, or
|
||||
@code{#f}.
|
||||
|
||||
@item
|
||||
@var{message}: a string (possibly language and system dependent)
|
||||
describing the error. The tokens @code{~A} and @code{~S} can be
|
||||
embedded within the message: they will be replaced with members of the
|
||||
@var{args} list when the message is printed. @code{~A} indicates an
|
||||
argument printed using @code{display}, while @code{~S} indicates an
|
||||
argument printed using @code{write}. @var{message} can also be
|
||||
@code{#f}, to allow it to be derived from the @var{key} by the error
|
||||
handler (may be useful if the @var{key} is to be thrown from both C and
|
||||
Scheme).
|
||||
|
||||
@item
|
||||
@var{args}: a list of arguments to be used to expand @code{~A} and
|
||||
@code{~S} tokens in @var{message}. Can also be @code{#f} if no
|
||||
arguments are required.
|
||||
|
||||
@item
|
||||
@var{rest}: a list of any additional objects required. e.g., when the
|
||||
key is @code{'system-error}, this contains the C errno value. Can also
|
||||
be @code{#f} if no additional objects are required.
|
||||
@end itemize
|
||||
|
||||
In addition to @code{catch} and @code{throw}, the following Scheme
|
||||
facilities are available:
|
||||
|
||||
@deffn {Scheme Procedure} scm-error key subr message args rest
|
||||
Throw an error, with arguments
|
||||
as described above.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} error msg arg @dots{}
|
||||
Throw an error using the key @code{'misc-error}. The error
|
||||
message is created by displaying @var{msg} and writing the @var{args}.
|
||||
@end deffn
|
||||
|
||||
The following are the error keys defined by libguile and the situations
|
||||
in which they are used:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
@code{error-signal}: thrown after receiving an unhandled fatal signal
|
||||
such as SIGSEGV, SIGBUS, SIGFPE etc. The @var{rest} argument in the throw
|
||||
contains the coded signal number (at present this is not the same as the
|
||||
usual Unix signal number).
|
||||
|
||||
@item
|
||||
@code{system-error}: thrown after the operating system indicates an
|
||||
error condition. The @var{rest} argument in the throw contains the
|
||||
errno value.
|
||||
|
||||
@item
|
||||
@code{numerical-overflow}: numerical overflow.
|
||||
|
||||
@item
|
||||
@code{out-of-range}: the arguments to a procedure do not fall within the
|
||||
accepted domain.
|
||||
|
||||
@item
|
||||
@code{wrong-type-arg}: an argument to a procedure has the wrong type.
|
||||
|
||||
@item
|
||||
@code{wrong-number-of-args}: a procedure was called with the wrong number
|
||||
of arguments.
|
||||
|
||||
@item
|
||||
@code{memory-allocation-error}: memory allocation error.
|
||||
|
||||
@item
|
||||
@code{stack-overflow}: stack overflow error.
|
||||
|
||||
@item
|
||||
@code{regex-error}: errors generated by the regular expression library.
|
||||
|
||||
@item
|
||||
@code{misc-error}: other errors.
|
||||
@end itemize
|
||||
|
||||
|
||||
@section C Support
|
||||
|
||||
SCM scm_error (SCM key, char *subr, char *message, SCM args, SCM rest)
|
||||
|
||||
Throws an error, after converting the char * arguments to Scheme strings.
|
||||
subr is the Scheme name of the procedure, NULL is converted to #f.
|
||||
Likewise a NULL message is converted to #f.
|
||||
|
||||
The following procedures invoke scm_error with various error keys and
|
||||
arguments. The first three call scm_error with the system-error key
|
||||
and automatically supply errno in the "rest" argument: scm_syserror
|
||||
generates messages using strerror, scm_sysmissing is used when
|
||||
facilities are not available. Care should be taken that the errno
|
||||
value is not reset (e.g. due to an interrupt).
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
void scm_syserror (char *subr);
|
||||
@item
|
||||
void scm_syserror_msg (char *subr, char *message, SCM args);
|
||||
@item
|
||||
void scm_sysmissing (char *subr);
|
||||
@item
|
||||
void scm_num_overflow (char *subr);
|
||||
@item
|
||||
void scm_out_of_range (char *subr, SCM bad_value);
|
||||
@item
|
||||
void scm_wrong_num_args (SCM proc);
|
||||
@item
|
||||
void scm_wrong_type_arg (char *subr, int pos, SCM bad_value);
|
||||
@item
|
||||
void scm_memory_error (char *subr);
|
||||
@item
|
||||
static void scm_regex_error (char *subr, int code); (only used in rgx.c).
|
||||
@end itemize
|
||||
|
||||
Exception handlers can also be installed from C, using
|
||||
scm_internal_catch, scm_lazy_catch, or scm_stack_catch from
|
||||
libguile/throw.c. These have not yet been documented, however the
|
||||
source contains some useful comments.
|
||||
|
||||
@c scm.texi ends here
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2002-03-16 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* filesys.c (scm_close): Fix stale cross reference in docstring.
|
||||
|
||||
2002-03-15 Thien-Thi Nguyen <ttn@giblet.glug.org>
|
||||
|
||||
* guile-snarf.in: Remove "--compat=1.4" support.
|
||||
|
|
|
@ -333,7 +333,7 @@ SCM_DEFINE (scm_open, "open", 2, 1, 0,
|
|||
|
||||
SCM_DEFINE (scm_close, "close", 1, 0, 0,
|
||||
(SCM fd_or_port),
|
||||
"Similar to close-port (@pxref{Generic Port Operations, close-port}),\n"
|
||||
"Similar to close-port (@pxref{Closing, close-port}),\n"
|
||||
"but also works on file descriptors. A side\n"
|
||||
"effect of closing a file descriptor is that any ports using that file\n"
|
||||
"descriptor are moved to a different file descriptor and have\n"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue