1 /* Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
42 /* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
48 #include "libguile/_scm.h"
50 #include "libguile/eval.h"
51 #include "libguile/ports.h"
52 #include "libguile/procprop.h"
53 #include "libguile/root.h"
54 #include "libguile/smob.h"
55 #include "libguile/strings.h"
57 #include "libguile/validate.h"
58 #include "libguile/feature.h"
65 static SCM
*scm_loc_features
;
68 scm_add_feature (const char *str
)
70 *scm_loc_features
= scm_cons (SCM_CAR (scm_intern (str
, strlen (str
))),
77 SCM_DEFINE (scm_program_arguments
, "program-arguments", 0, 0, 0,
80 #define FUNC_NAME s_scm_program_arguments
86 /* Set the value returned by program-arguments, given ARGC and ARGV.
88 If FIRST is non-zero, make it the first element; we do this in
89 situations where other code (like getopt) has parsed out a few
90 arguments, but we still want the script name to be the first
93 scm_set_program_arguments (int argc
, char **argv
, char *first
)
95 scm_progargs
= scm_makfromstrs (argc
, argv
);
97 scm_progargs
= scm_cons (scm_makfrom0str (first
), scm_progargs
);
104 * A hook is basically a list of procedures to be called at well defined
107 * Hook name and arity are not full members of this type and therefore
108 * lack accessors. They are added to aid debugging and are not
109 * intended to be used in programs.
117 make_hook (SCM name
, SCM n_args
, const char *subr
)
120 SCM_ASSERT (SCM_FALSEP (name
) || (SCM_SYMBOLP (name
)),
124 if (SCM_UNBNDP (n_args
))
128 SCM_ASSERT (SCM_INUMP (n_args
), n_args
, SCM_ARGn
, subr
);
129 n
= SCM_INUM (n_args
);
131 SCM_ASSERT (n
>= 0 && n
<= 16, n_args
, SCM_OUTOFRANGE
, subr
);
132 SCM_RETURN_NEWSMOB (scm_tc16_hook
+ (n
<< 16), SCM_UNPACK (SCM_LIST1 (name
)));
137 print_hook (SCM hook
, SCM port
, scm_print_state
*pstate
)
140 scm_puts ("#<hook ", port
);
141 if (SCM_NFALSEP (SCM_HOOK_NAME (hook
)))
143 scm_iprin1 (SCM_HOOK_NAME (hook
), port
, pstate
);
144 scm_putc (' ', port
);
146 scm_intprint (SCM_HOOK_ARITY (hook
), 10, port
);
147 scm_putc (' ', port
);
148 scm_intprint (SCM_UNPACK (hook
), 16, port
);
149 ls
= SCM_HOOK_PROCEDURES (hook
);
150 while (SCM_NIMP (ls
))
152 scm_putc (' ', port
);
153 name
= scm_procedure_name (SCM_CAR (ls
));
154 if (SCM_NFALSEP (name
))
155 scm_iprin1 (name
, port
, pstate
);
157 scm_putc ('?', port
);
160 scm_putc ('>', port
);
166 scm_create_hook (const char* name
, int n_args
)
168 SCM vcell
= scm_sysintern0 (name
);
169 SCM hook
= make_hook (SCM_CAR (vcell
), SCM_MAKINUM (n_args
),
171 SCM_SETCDR (vcell
, hook
);
172 scm_protect_object (vcell
);
177 /* This function is deprecated. It will be removed in next release. */
179 scm_make_named_hook (const char* name
, int n_args
)
181 return scm_create_hook (name
, n_args
);
185 SCM_DEFINE (scm_make_hook_with_name
, "make-hook-with-name", 1, 1, 0,
186 (SCM name
, SCM n_args
),
188 #define FUNC_NAME s_scm_make_hook_with_name
190 return make_hook (name
, n_args
, FUNC_NAME
);
195 SCM_DEFINE (scm_make_hook
, "make-hook", 0, 1, 0,
198 #define FUNC_NAME s_scm_make_hook
200 return make_hook (SCM_BOOL_F
, n_args
, FUNC_NAME
);
205 SCM_DEFINE (scm_hook_p
, "hook?", 1, 0, 0,
208 #define FUNC_NAME s_scm_hook_p
210 return SCM_BOOL(SCM_HOOKP (x
));
215 SCM_DEFINE (scm_hook_empty_p
, "hook-empty?", 1, 0, 0,
218 #define FUNC_NAME s_scm_hook_empty_p
220 SCM_VALIDATE_HOOK (1,hook
);
221 return SCM_BOOL(SCM_NULLP (SCM_HOOK_PROCEDURES (hook
)));
226 SCM_DEFINE (scm_add_hook_x
, "add-hook!", 2, 1, 0,
227 (SCM hook
, SCM proc
, SCM append_p
),
229 #define FUNC_NAME s_scm_add_hook_x
233 SCM_VALIDATE_HOOK (1,hook
);
234 SCM_ASSERT (SCM_NFALSEP (arity
= scm_i_procedure_arity (proc
)),
235 proc
, SCM_ARG2
, FUNC_NAME
);
236 n_args
= SCM_HOOK_ARITY (hook
);
237 if (SCM_INUM (SCM_CAR (arity
)) > n_args
238 || (SCM_FALSEP (SCM_CADDR (arity
))
239 && (SCM_INUM (SCM_CAR (arity
)) + SCM_INUM (SCM_CADR (arity
))
241 scm_wrong_type_arg (FUNC_NAME
, 2, proc
);
242 rest
= scm_delq_x (proc
, SCM_HOOK_PROCEDURES (hook
));
243 SCM_SET_HOOK_PROCEDURES (hook
,
244 (!SCM_UNBNDP (append_p
) && SCM_NFALSEP (append_p
)
245 ? scm_append_x (SCM_LIST2 (rest
, SCM_LIST1 (proc
)))
246 : scm_cons (proc
, rest
)));
247 return SCM_UNSPECIFIED
;
252 SCM_DEFINE (scm_remove_hook_x
, "remove-hook!", 2, 0, 0,
253 (SCM hook
, SCM proc
),
255 #define FUNC_NAME s_scm_remove_hook_x
257 SCM_VALIDATE_HOOK (1,hook
);
258 SCM_SET_HOOK_PROCEDURES (hook
,
259 scm_delq_x (proc
, SCM_HOOK_PROCEDURES (hook
)));
260 return SCM_UNSPECIFIED
;
265 SCM_DEFINE (scm_reset_hook_x
, "reset-hook!", 1, 0, 0,
268 #define FUNC_NAME s_scm_reset_hook_x
270 SCM_VALIDATE_HOOK (1,hook
);
271 SCM_SET_HOOK_PROCEDURES (hook
, SCM_EOL
);
272 return SCM_UNSPECIFIED
;
277 SCM_DEFINE (scm_run_hook
, "run-hook", 1, 0, 1,
278 (SCM hook
, SCM args
),
280 #define FUNC_NAME s_scm_run_hook
282 SCM_VALIDATE_HOOK (1,hook
);
283 if (SCM_UNBNDP (args
))
285 if (scm_ilength (args
) != SCM_HOOK_ARITY (hook
))
286 SCM_MISC_ERROR ("Hook ~S requires ~A arguments",
287 SCM_LIST2 (hook
,SCM_MAKINUM (SCM_HOOK_ARITY (hook
))));
288 scm_c_run_hook (hook
, args
);
289 return SCM_UNSPECIFIED
;
295 scm_c_run_hook (SCM hook
, SCM args
)
297 SCM procs
= SCM_HOOK_PROCEDURES (hook
);
298 while (SCM_NIMP (procs
))
300 scm_apply (SCM_CAR (procs
), args
, SCM_EOL
);
301 procs
= SCM_CDR (procs
);
306 SCM_DEFINE (scm_hook_to_list
, "hook->list", 1, 0, 0,
309 #define FUNC_NAME s_scm_hook_to_list
311 SCM_VALIDATE_HOOK (1,hook
);
312 return scm_list_copy (SCM_HOOK_PROCEDURES (hook
));
322 scm_loc_features
= SCM_CDRLOC (scm_sysintern ("*features*", SCM_EOL
));
324 scm_add_feature("reckless");
327 scm_add_feature("system");
330 scm_add_feature(s_ed
);
333 scm_add_feature("sicp");
336 scm_add_feature("char-ready?");
338 #ifndef CHEAP_CONTINUATIONS
339 scm_add_feature ("full-continuation");
342 scm_add_feature ("threads");
345 scm_sysintern ("char-code-limit", SCM_MAKINUM (SCM_CHAR_CODE_LIMIT
));
347 scm_tc16_hook
= scm_make_smob_type ("hook", 0);
348 scm_set_smob_mark (scm_tc16_hook
, scm_markcdr
);
349 scm_set_smob_print (scm_tc16_hook
, print_hook
);
351 #include "libguile/feature.x"