1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

* Manual updates on hooks and features.

* Fix scm_t_c_hookype_t corruption.
This commit is contained in:
Neil Jerram 2002-03-16 00:27:25 +00:00
parent b193d130d8
commit 387d418c55
8 changed files with 429 additions and 37 deletions

View file

@ -8,6 +8,13 @@
2002-03-15 Neil Jerram <neil@ossau.uklinux.net>
* scheme-utility.texi (Hooks): Reviewed and updated.
* scheme-options.texi (Feature Tracking): New section.
* scheme-data.texi (Arithmetic, Primitive Numerics): Add
description of corresponding C functions.
* scheme-utility.texi (Object Properties): Revamp documentation on
object properties.

View file

@ -714,7 +714,11 @@ called with one argument @var{z1}, 1/@var{z1} is returned.
@c begin (texi-doc-string "guile" "abs")
@deffn {Scheme Procedure} abs x
@deffnx {C Function} scm_abs (x)
Return the absolute value of @var{x}.
@var{x} must be a number with zero imaginary part. To calculate the
magnitude of a complex number, use @code{magnitude} instead.
@end deffn
@c begin (texi-doc-string "guile" "max")
@ -747,6 +751,18 @@ Round the number @var{x} towards minus infinity.
Round the number @var{x} towards infinity.
@end deffn
For the @code{truncate} and @code{round} procedures, the Guile library
exports equivalent C functions, but taking and returning arguments of
type @code{double} rather than the usual @code{SCM}.
@deftypefn {C Function} double scm_truncate (double x)
@deftypefnx {C Function} double scm_round (double x)
@end deftypefn
For @code{floor} and @code{ceiling}, the equivalent C functions are
@code{floor} and @code{ceil} from the standard mathematics library
(which also take and return @code{double} arguments).
@node Scientific
@subsection Scientific Functions
@ -955,6 +971,43 @@ Return the hyperbolic arccosine of @var{x}.
Return the hyperbolic arctangent of @var{x}.
@end deffn
For the hyperbolic arc-functions, the Guile library exports C functions
corresponding to these Scheme procedures, but taking and returning
arguments of type @code{double} rather than the usual @code{SCM}.
@deftypefn {C Function} double scm_asinh (double x)
@deftypefnx {C Function} double scm_acosh (double x)
@deftypefnx {C Function} double scm_atanh (double x)
Return the hyperbolic arcsine, arccosine or arctangent of @var{x}
respectively.
@end deftypefn
For all the other Scheme procedures above, except @code{expt} and
@code{atan2} (whose entries specifically mention an equivalent C
function), the equivalent C functions are those provided by the standard
mathematics library. The mapping is as follows.
@multitable {xx} {Scheme Procedure} {C Function}
@item @tab Scheme Procedure @tab C Function
@item @tab @code{$abs} @tab @code{fabs}
@item @tab @code{$sqrt} @tab @code{sqrt}
@item @tab @code{$sin} @tab @code{sin}
@item @tab @code{$cos} @tab @code{cos}
@item @tab @code{$tan} @tab @code{tan}
@item @tab @code{$asin} @tab @code{asin}
@item @tab @code{$acos} @tab @code{acos}
@item @tab @code{$atan} @tab @code{atan}
@item @tab @code{$exp} @tab @code{exp}
@item @tab @code{$log} @tab @code{log}
@item @tab @code{$sinh} @tab @code{sinh}
@item @tab @code{$cosh} @tab @code{cosh}
@item @tab @code{$tanh} @tab @code{tanh}
@end multitable
@noindent
Naturally, these C functions expect and return @code{double} arguments.
@node Bitwise Operations
@subsection Bitwise Operations

View file

@ -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
@ -431,6 +432,186 @@ 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"
@c End:

View file

@ -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,11 +540,128 @@ 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.
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}.
@deffn {C Type} scm_t_c_hook
Data type for a C hook. The internals of this type should be treated as
opaque.
@end deffn
@deffn {C Enum} scm_t_c_hook_type
Enumeration of possible hook types, which are:
@table @code
@item SCM_C_HOOK_NORMAL
Type of hook for which all the registered functions will always be called.
@item 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
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 deffn
@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
@deffn {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 deffn
@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
@table @code
@item scm_before_gc_c_hook
@item scm_before_mark_c_hook
@item scm_before_sweep_c_hook
@item scm_after_sweep_c_hook
@item scm_after_gc_c_hook
@end table
@c Local Variables:
@c TeX-master: "guile.texi"

View file

@ -10,6 +10,9 @@
2002-03-15 Neil Jerram <neil@ossau.uklinux.net>
* hooks.h: Change scm_t_c_hookype_t everywhere to
scm_t_c_hook_type.
Docstring fixes:
* strings.c (scm_string_p): Change unnecessary `iff' to `if'.

View file

@ -212,7 +212,7 @@ SCM_DEFINE (scm_setvbuf, "setvbuf", 2, 1, 0,
#undef FUNC_NAME
/* Move ports with the specified file descriptor to new descriptors,
* reseting the revealed count to 0.
* resetting the revealed count to 0.
*/
void

View file

@ -64,7 +64,7 @@
*/
void
scm_c_hook_init (scm_t_c_hook *hook, void *hook_data, scm_t_c_hookype_t type)
scm_c_hook_init (scm_t_c_hook *hook, void *hook_data, scm_t_c_hook_type type)
{
hook->first = 0;
hook->type = type;
@ -113,7 +113,7 @@ void *
scm_c_hook_run (scm_t_c_hook *hook, void *data)
{
scm_t_c_hook_entry *entry = hook->first;
scm_t_c_hookype_t type = hook->type;
scm_t_c_hook_type type = hook->type;
void *res = 0;
while (entry)
{

View file

@ -57,11 +57,11 @@
* both may want to indicate success/failure and return a result.
*/
typedef enum scm_t_c_hookype_t {
typedef enum scm_t_c_hook_type {
SCM_C_HOOK_NORMAL,
SCM_C_HOOK_OR,
SCM_C_HOOK_AND
} scm_t_c_hookype_t;
} scm_t_c_hook_type;
typedef void *(*scm_t_c_hook_function) (void *hook_data,
void *func_data,
@ -75,13 +75,13 @@ typedef struct scm_t_c_hook_entry {
typedef struct scm_t_c_hook {
scm_t_c_hook_entry *first;
scm_t_c_hookype_t type;
scm_t_c_hook_type type;
void *data;
} scm_t_c_hook;
SCM_API void scm_c_hook_init (scm_t_c_hook *hook,
void *hook_data,
scm_t_c_hookype_t type);
scm_t_c_hook_type type);
SCM_API void scm_c_hook_add (scm_t_c_hook *hook,
scm_t_c_hook_function func,
void *func_data,