Only include strings.h where it is actually needed.
[bpt/guile.git] / libguile / feature.c
CommitLineData
78a0461a 1/* Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
0f2d19dd
JB
2 *
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)
6 * any later version.
7 *
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.
12 *
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
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
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.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
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.
37 *
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.
82892bed 40 * If you do not wish that, delete this exception notice. */
1bbd0b84
GB
41
42/* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
44
0f2d19dd
JB
45\f
46
47#include <stdio.h>
48#include "_scm.h"
49
1330700c 50#include "eval.h"
f04d8caf 51#include "ports.h"
b90d369e 52#include "procprop.h"
26425129 53#include "smob.h"
7ab3fdd5 54#include "strings.h"
1330700c 55
b6791b2e 56#include "validate.h"
20e6290e
JB
57#include "feature.h"
58
95b88819
GH
59#ifdef HAVE_STRING_H
60#include <string.h>
61#endif
0f2d19dd
JB
62\f
63
f072db0c 64static SCM *scm_loc_features;
0f2d19dd 65
0f2d19dd 66void
6e8d25a6 67scm_add_feature (const char *str)
0f2d19dd 68{
b90d369e
MD
69 *scm_loc_features = scm_cons (SCM_CAR (scm_intern (str, strlen (str))),
70 *scm_loc_features);
0f2d19dd
JB
71}
72
73
74\f
0b886892 75
3b3b36dd 76SCM_DEFINE (scm_program_arguments, "program-arguments", 0, 0, 0,
1bbd0b84
GB
77 (),
78"")
79#define FUNC_NAME s_scm_program_arguments
0f2d19dd
JB
80{
81 return scm_progargs;
82}
1bbd0b84 83#undef FUNC_NAME
0f2d19dd 84
f29de790
JB
85/* Set the value returned by program-arguments, given ARGC and ARGV.
86
87 If FIRST is non-zero, make it the first element; we do this in
88 situations where other code (like getopt) has parsed out a few
89 arguments, but we still want the script name to be the first
90 element. */
0b886892 91void
1bbd0b84 92scm_set_program_arguments (int argc, char **argv, char *first)
0b886892
JB
93{
94 scm_progargs = scm_makfromstrs (argc, argv);
f29de790
JB
95 if (first)
96 scm_progargs = scm_cons (scm_makfrom0str (first), scm_progargs);
0b886892
JB
97}
98
0f2d19dd 99
0f2d19dd 100\f
36399a6d
MD
101/* Hooks
102 *
103 * A hook is basically a list of procedures to be called at well defined
104 * points in time.
105 *
106 * Hook name and arity are not full members of this type and therefore
107 * lack accessors. They are added to aid debugging and are not
108 * intended to be used in programs.
109 *
110 */
1330700c 111
26425129
MD
112long scm_tc16_hook;
113
1330700c 114
36399a6d
MD
115static SCM
116make_hook (SCM name, SCM n_args, const char *subr)
1330700c 117{
26425129 118 int n;
0c95b57d 119 SCM_ASSERT (SCM_FALSEP (name) || (SCM_SYMBOLP (name)),
36399a6d
MD
120 name,
121 SCM_ARG1,
122 subr);
b90d369e 123 if (SCM_UNBNDP (n_args))
26425129 124 n = 0;
b90d369e 125 else
26425129 126 {
36399a6d 127 SCM_ASSERT (SCM_INUMP (n_args), n_args, SCM_ARGn, subr);
26425129
MD
128 n = SCM_INUM (n_args);
129 }
36399a6d
MD
130 SCM_ASSERT (n >= 0 && n <= 16, n_args, SCM_OUTOFRANGE, subr);
131 SCM_RETURN_NEWSMOB (scm_tc16_hook + (n << 16), SCM_LIST1 (name));
132}
133
134
135static int
136print_hook (SCM hook, SCM port, scm_print_state *pstate)
137{
138 SCM ls, name;
139 scm_puts ("#<hook ", port);
140 if (SCM_NFALSEP (SCM_HOOK_NAME (hook)))
141 {
142 scm_iprin1 (SCM_HOOK_NAME (hook), port, pstate);
143 scm_putc (' ', port);
144 }
145 scm_intprint (SCM_HOOK_ARITY (hook), 10, port);
146 scm_putc (' ', port);
c209c88e 147 scm_intprint ((int)hook, 16, port);
36399a6d
MD
148 ls = SCM_HOOK_PROCEDURES (hook);
149 while (SCM_NIMP (ls))
150 {
151 scm_putc (' ', port);
152 name = scm_procedure_name (SCM_CAR (ls));
153 if (SCM_NFALSEP (name))
154 scm_iprin1 (name, port, pstate);
155 else
156 scm_putc ('?', port);
157 ls = SCM_CDR (ls);
158 }
159 scm_putc ('>', port);
160 return 1;
1330700c
MD
161}
162
26425129 163
1330700c 164SCM
36399a6d 165scm_create_hook (const char* name, int n_args)
1330700c 166{
36399a6d
MD
167 SCM vcell = scm_sysintern0 (name);
168 SCM hook = make_hook (SCM_CAR (vcell), SCM_MAKINUM (n_args),
169 "scm_create_hook");
170 SCM_SETCDR (vcell, hook);
171 scm_protect_object (vcell);
1330700c
MD
172 return hook;
173}
174
26425129 175
36399a6d
MD
176/* This function is deprecated. It will be removed in next release. */
177SCM
178scm_make_named_hook (const char* name, int n_args)
179{
180 return scm_create_hook (name, n_args);
181}
182
183
a1ec6916 184SCM_DEFINE (scm_make_hook_with_name, "make-hook-with-name", 1, 1, 0,
1bbd0b84
GB
185 (SCM name, SCM n_args),
186"")
187#define FUNC_NAME s_scm_make_hook_with_name
36399a6d 188{
1bbd0b84 189 return make_hook (name, n_args, FUNC_NAME);
36399a6d 190}
1bbd0b84 191#undef FUNC_NAME
36399a6d
MD
192
193
a1ec6916 194SCM_DEFINE (scm_make_hook, "make-hook", 0, 1, 0,
1bbd0b84
GB
195 (SCM n_args),
196"")
197#define FUNC_NAME s_scm_make_hook
36399a6d 198{
1bbd0b84 199 return make_hook (SCM_BOOL_F, n_args, FUNC_NAME);
36399a6d 200}
1bbd0b84 201#undef FUNC_NAME
36399a6d
MD
202
203
a1ec6916 204SCM_DEFINE (scm_hook_p, "hook?", 1, 0, 0,
1bbd0b84
GB
205 (SCM x),
206"")
207#define FUNC_NAME s_scm_hook_p
26425129 208{
0c95b57d 209 return SCM_BOOL(SCM_HOOKP (x));
26425129 210}
1bbd0b84 211#undef FUNC_NAME
26425129
MD
212
213
a1ec6916 214SCM_DEFINE (scm_hook_empty_p, "hook-empty?", 1, 0, 0,
1bbd0b84
GB
215 (SCM hook),
216"")
217#define FUNC_NAME s_scm_hook_empty_p
26425129 218{
3b3b36dd 219 SCM_VALIDATE_HOOK (1,hook);
1bbd0b84 220 return SCM_BOOL(SCM_NULLP (SCM_HOOK_PROCEDURES (hook)));
26425129 221}
1bbd0b84 222#undef FUNC_NAME
26425129
MD
223
224
a1ec6916 225SCM_DEFINE (scm_add_hook_x, "add-hook!", 2, 1, 0,
1bbd0b84
GB
226 (SCM hook, SCM proc, SCM append_p),
227"")
228#define FUNC_NAME s_scm_add_hook_x
1330700c 229{
b90d369e
MD
230 SCM arity, rest;
231 int n_args;
3b3b36dd 232 SCM_VALIDATE_HOOK (1,hook);
b90d369e 233 SCM_ASSERT (SCM_NFALSEP (arity = scm_i_procedure_arity (proc)),
1bbd0b84 234 proc, SCM_ARG2, FUNC_NAME);
26425129 235 n_args = SCM_HOOK_ARITY (hook);
b90d369e
MD
236 if (SCM_INUM (SCM_CAR (arity)) > n_args
237 || (SCM_FALSEP (SCM_CADDR (arity))
238 && (SCM_INUM (SCM_CAR (arity)) + SCM_INUM (SCM_CADR (arity))
239 < n_args)))
1834aa1b 240 scm_wrong_type_arg (FUNC_NAME, 2, proc);
26425129
MD
241 rest = scm_delq_x (proc, SCM_HOOK_PROCEDURES (hook));
242 SCM_SET_HOOK_PROCEDURES (hook,
243 (!SCM_UNBNDP (append_p) && SCM_NFALSEP (append_p)
244 ? scm_append_x (SCM_LIST2 (rest, SCM_LIST1 (proc)))
245 : scm_cons (proc, rest)));
1330700c
MD
246 return SCM_UNSPECIFIED;
247}
1bbd0b84 248#undef FUNC_NAME
1330700c 249
26425129 250
a1ec6916 251SCM_DEFINE (scm_remove_hook_x, "remove-hook!", 2, 0, 0,
1bbd0b84
GB
252 (SCM hook, SCM proc),
253"")
254#define FUNC_NAME s_scm_remove_hook_x
1330700c 255{
3b3b36dd 256 SCM_VALIDATE_HOOK (1,hook);
26425129
MD
257 SCM_SET_HOOK_PROCEDURES (hook,
258 scm_delq_x (proc, SCM_HOOK_PROCEDURES (hook)));
1330700c
MD
259 return SCM_UNSPECIFIED;
260}
1bbd0b84 261#undef FUNC_NAME
1330700c 262
26425129 263
a1ec6916 264SCM_DEFINE (scm_reset_hook_x, "reset-hook!", 1, 0, 0,
1bbd0b84
GB
265 (SCM hook),
266"")
267#define FUNC_NAME s_scm_reset_hook_x
1330700c 268{
3b3b36dd 269 SCM_VALIDATE_HOOK (1,hook);
26425129 270 SCM_SET_HOOK_PROCEDURES (hook, SCM_EOL);
b90d369e
MD
271 return SCM_UNSPECIFIED;
272}
1bbd0b84 273#undef FUNC_NAME
b90d369e 274
26425129 275
a1ec6916 276SCM_DEFINE (scm_run_hook, "run-hook", 1, 0, 1,
1bbd0b84
GB
277 (SCM hook, SCM args),
278"")
279#define FUNC_NAME s_scm_run_hook
b90d369e 280{
3b3b36dd 281 SCM_VALIDATE_HOOK (1,hook);
b90d369e
MD
282 if (SCM_UNBNDP (args))
283 args = SCM_EOL;
26425129 284 if (scm_ilength (args) != SCM_HOOK_ARITY (hook))
5d2d2ffc 285 SCM_MISC_ERROR ("Hook ~S requires ~A arguments",
70d63753 286 SCM_LIST2 (hook,SCM_MAKINUM (SCM_HOOK_ARITY (hook))));
ef1ae563
MD
287 scm_c_run_hook (hook, args);
288 return SCM_UNSPECIFIED;
289}
1bbd0b84 290#undef FUNC_NAME
ef1ae563 291
26425129 292
ef1ae563
MD
293void
294scm_c_run_hook (SCM hook, SCM args)
295{
26425129
MD
296 SCM procs = SCM_HOOK_PROCEDURES (hook);
297 while (SCM_NIMP (procs))
298 {
299 scm_apply (SCM_CAR (procs), args, SCM_EOL);
300 procs = SCM_CDR (procs);
301 }
302}
303
304
a1ec6916 305SCM_DEFINE (scm_hook_to_list, "hook->list", 1, 0, 0,
1bbd0b84 306 (SCM hook),
717050c8 307"")
1bbd0b84 308#define FUNC_NAME s_scm_hook_to_list
26425129 309{
3b3b36dd 310 SCM_VALIDATE_HOOK (1,hook);
26425129 311 return scm_list_copy (SCM_HOOK_PROCEDURES (hook));
1330700c 312}
1bbd0b84 313#undef FUNC_NAME
1330700c 314
26425129 315
1330700c 316\f
0f2d19dd 317
0f2d19dd
JB
318void
319scm_init_feature()
0f2d19dd 320{
25d8012c 321 scm_loc_features = SCM_CDRLOC (scm_sysintern ("*features*", SCM_EOL));
cf7c17e9 322#ifdef SCM_RECKLESS
0f2d19dd
JB
323 scm_add_feature("reckless");
324#endif
325#ifndef _Windows
326 scm_add_feature("system");
327#endif
328#ifdef vms
329 scm_add_feature(s_ed);
330#endif
331#ifdef SICP
332 scm_add_feature("sicp");
333#endif
334#ifndef GO32
335 scm_add_feature("char-ready?");
336#endif
337#ifndef CHEAP_CONTINUATIONS
338 scm_add_feature ("full-continuation");
339#endif
a6cba733
MD
340#ifdef USE_THREADS
341 scm_add_feature ("threads");
342#endif
343
e2806c10 344 scm_sysintern ("char-code-limit", SCM_MAKINUM (SCM_CHAR_CODE_LIMIT));
26425129
MD
345
346 scm_tc16_hook = scm_make_smob_type ("hook", 0);
347 scm_set_smob_mark (scm_tc16_hook, scm_markcdr);
36399a6d 348 scm_set_smob_print (scm_tc16_hook, print_hook);
26425129 349
0f2d19dd
JB
350#include "feature.x"
351}