1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00
guile/libguile/hooks.c
Andy Wingo 730cfd80e2 Devolve pairs.h
* libguile/_scm.h: Remove pairs.h.
* libguile/alist.c:
* libguile/array-handle.c:
* libguile/array-map.c:
* libguile/arrays.c:
* libguile/async.c:
* libguile/bitvectors.c:
* libguile/bytevectors.c:
* libguile/chars.c:
* libguile/continuations.c:
* libguile/control.c:
* libguile/debug.c:
* libguile/deprecation.c:
* libguile/dynwind.c:
* libguile/eq.c:
* libguile/eval.c:
* libguile/evalext.c:
* libguile/expand.c:
* libguile/fdes-finalizers.c:
* libguile/feature.c:
* libguile/filesys.c:
* libguile/fluids.c:
* libguile/foreign.c:
* libguile/fports.c:
* libguile/gc.c:
* libguile/generalized-arrays.c:
* libguile/goops.c:
* libguile/guardians.c:
* libguile/hash.c:
* libguile/hashtab.c:
* libguile/hooks.c:
* libguile/i18n.c:
* libguile/instructions.c:
* libguile/ioext.c:
* libguile/keywords.c:
* libguile/list.c:
* libguile/load.c:
* libguile/loader.c:
* libguile/memoize.c:
* libguile/modules.c:
* libguile/net_db.c:
* libguile/numbers.c:
* libguile/objprop.c:
* libguile/options.c:
* libguile/ports-internal.h:
* libguile/ports.c:
* libguile/posix.c:
* libguile/print.c:
* libguile/print.h:
* libguile/procprop.c:
* libguile/programs.c:
* libguile/random.c:
* libguile/rdelim.c:
* libguile/read.c:
* libguile/regex-posix.c:
* libguile/scmsigs.c:
* libguile/script.c:
* libguile/socket.c:
* libguile/sort.c:
* libguile/srcprop.c:
* libguile/srfi-1.c:
* libguile/srfi-13.c:
* libguile/srfi-14.c:
* libguile/srfi-60.c:
* libguile/stacks.c:
* libguile/stime.c:
* libguile/strings.c:
* libguile/strorder.c:
* libguile/struct.c:
* libguile/symbols.c:
* libguile/threads.c:
* libguile/throw.c:
* libguile/trees.c:
* libguile/values.c:
* libguile/vectors.c:
* libguile/vm.c:
* libguile/weak-list.h:
* libguile/weak-set.c:
* libguile/weak-table.c:
* libguile/weak-vector.c: Add pairs.h.
2018-06-18 22:03:13 +02:00

237 lines
6.3 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Copyright (C) 1995-1996,1998-2001,2003,2006,2008-2009,2011,2018
* Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include "libguile/_scm.h"
#include "libguile/pairs.h"
#include "libguile/boolean.h"
#include "libguile/eval.h"
#include "libguile/list.h"
#include "libguile/ports.h"
#include "libguile/procprop.h"
#include "libguile/smob.h"
#include "libguile/strings.h"
#include "libguile/hooks.h"
/* Scheme level hooks
*
* A hook is basically a list of procedures to be called at well defined
* points in time.
*
* Hook arity is not a full member of this type and therefore lacks an
* accessor. It exists to aid debugging and is not intended to be used in
* programs.
*/
scm_t_bits scm_tc16_hook;
static int
hook_print (SCM hook, SCM port, scm_print_state *pstate)
{
SCM ls, name;
scm_puts ("#<hook ", port);
scm_intprint (SCM_HOOK_ARITY (hook), 10, port);
scm_putc (' ', port);
scm_uintprint (SCM_UNPACK (hook), 16, port);
ls = SCM_HOOK_PROCEDURES (hook);
while (scm_is_pair (ls))
{
scm_putc (' ', port);
name = scm_procedure_name (SCM_CAR (ls));
if (scm_is_true (name))
scm_iprin1 (name, port, pstate);
else
scm_putc ('?', port);
ls = SCM_CDR (ls);
}
scm_putc ('>', port);
return 1;
}
SCM_DEFINE (scm_make_hook, "make-hook", 0, 1, 0,
(SCM n_args),
"Create a hook for storing procedure of arity @var{n_args}.\n"
"@var{n_args} defaults to zero. The returned value is a hook\n"
"object to be used with the other hook procedures.")
#define FUNC_NAME s_scm_make_hook
{
unsigned int n;
if (SCM_UNBNDP (n_args))
n = 0;
else
n = scm_to_unsigned_integer (n_args, 0, 16);
SCM_RETURN_NEWSMOB (scm_tc16_hook + (n << 16), SCM_UNPACK (SCM_EOL));
}
#undef FUNC_NAME
SCM_DEFINE (scm_hook_p, "hook?", 1, 0, 0,
(SCM x),
"Return @code{#t} if @var{x} is a hook, @code{#f} otherwise.")
#define FUNC_NAME s_scm_hook_p
{
return scm_from_bool (SCM_HOOKP (x));
}
#undef FUNC_NAME
SCM_DEFINE (scm_hook_empty_p, "hook-empty?", 1, 0, 0,
(SCM hook),
"Return @code{#t} if @var{hook} is an empty hook, @code{#f}\n"
"otherwise.")
#define FUNC_NAME s_scm_hook_empty_p
{
SCM_VALIDATE_HOOK (1, hook);
return scm_from_bool (scm_is_null (SCM_HOOK_PROCEDURES (hook)));
}
#undef FUNC_NAME
SCM_DEFINE (scm_add_hook_x, "add-hook!", 2, 1, 0,
(SCM hook, SCM proc, SCM append_p),
"Add the procedure @var{proc} to the hook @var{hook}. The\n"
"procedure is added to the end if @var{append_p} is true,\n"
"otherwise it is added to the front. The return value of this\n"
"procedure is not specified.")
#define FUNC_NAME s_scm_add_hook_x
{
SCM rest;
int n_args, p_req, p_opt, p_rest;
SCM_VALIDATE_HOOK (1, hook);
SCM_ASSERT (scm_i_procedure_arity (proc, &p_req, &p_opt, &p_rest),
proc, SCM_ARG2, FUNC_NAME);
n_args = SCM_HOOK_ARITY (hook);
if (p_req > n_args || (!p_rest && p_req + p_opt < n_args))
scm_wrong_type_arg (FUNC_NAME, 2, proc);
rest = scm_delq_x (proc, SCM_HOOK_PROCEDURES (hook));
SCM_SET_HOOK_PROCEDURES (hook,
(!SCM_UNBNDP (append_p) && scm_is_true (append_p)
? scm_append_x (scm_list_2 (rest, scm_list_1 (proc)))
: scm_cons (proc, rest)));
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
SCM_DEFINE (scm_remove_hook_x, "remove-hook!", 2, 0, 0,
(SCM hook, SCM proc),
"Remove the procedure @var{proc} from the hook @var{hook}. The\n"
"return value of this procedure is not specified.")
#define FUNC_NAME s_scm_remove_hook_x
{
SCM_VALIDATE_HOOK (1, hook);
SCM_SET_HOOK_PROCEDURES (hook,
scm_delq_x (proc, SCM_HOOK_PROCEDURES (hook)));
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
SCM_DEFINE (scm_reset_hook_x, "reset-hook!", 1, 0, 0,
(SCM hook),
"Remove all procedures from the hook @var{hook}. The return\n"
"value of this procedure is not specified.")
#define FUNC_NAME s_scm_reset_hook_x
{
SCM_VALIDATE_HOOK (1, hook);
SCM_SET_HOOK_PROCEDURES (hook, SCM_EOL);
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
SCM_DEFINE (scm_run_hook, "run-hook", 1, 0, 1,
(SCM hook, SCM args),
"Apply all procedures from the hook @var{hook} to the arguments\n"
"@var{args}. The order of the procedure application is first to\n"
"last. The return value of this procedure is not specified.")
#define FUNC_NAME s_scm_run_hook
{
SCM_VALIDATE_HOOK (1, hook);
if (scm_ilength (args) != SCM_HOOK_ARITY (hook))
SCM_MISC_ERROR ("Hook ~S requires ~A arguments",
scm_list_2 (hook, scm_from_int (SCM_HOOK_ARITY (hook))));
scm_c_run_hook (hook, args);
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
void
scm_c_run_hook (SCM hook, SCM args)
{
SCM procs = SCM_HOOK_PROCEDURES (hook);
while (scm_is_pair (procs))
{
scm_apply_0 (SCM_CAR (procs), args);
procs = SCM_CDR (procs);
}
}
void
scm_c_run_hookn (SCM hook, SCM *argv, size_t nargs)
{
SCM procs = SCM_HOOK_PROCEDURES (hook);
while (scm_is_pair (procs))
{
scm_call_n (SCM_CAR (procs), argv, nargs);
procs = SCM_CDR (procs);
}
}
SCM_DEFINE (scm_hook_to_list, "hook->list", 1, 0, 0,
(SCM hook),
"Convert the procedure list of @var{hook} to a list.")
#define FUNC_NAME s_scm_hook_to_list
{
SCM_VALIDATE_HOOK (1, hook);
return scm_list_copy (SCM_HOOK_PROCEDURES (hook));
}
#undef FUNC_NAME
void
scm_init_hooks ()
{
scm_tc16_hook = scm_make_smob_type ("hook", 0);
scm_set_smob_print (scm_tc16_hook, hook_print);
#include "libguile/hooks.x"
}
/*
Local Variables:
c-file-style: "gnu"
End:
*/