*** empty log message ***
[bpt/guile.git] / libguile / error.c
CommitLineData
0f2d19dd
JB
1/* Copyright (C) 1995,1996 Free Software Foundation, Inc.
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
15 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16 *
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
19 *
20 * The exception is that, if you link the GUILE library with other files
21 * to produce an executable, this does not by itself cause the
22 * resulting executable to be covered by the GNU General Public License.
23 * Your use of that executable is in no way restricted on account of
24 * linking the GUILE library code into it.
25 *
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
28 *
29 * This exception applies only to the code released by the
30 * Free Software Foundation under the name GUILE. If you copy
31 * code from other Free Software Foundation releases into a copy of
32 * GUILE, as the General Public License permits, the exception does
33 * not apply to the code that you add in this way. To avoid misleading
34 * anyone as to the status of such modified files, you must delete
35 * this exception notice from them.
36 *
37 * If you write modifications of your own for GUILE, it is your choice
38 * whether to permit this exception to apply to your modifications.
39 * If you do not wish that, delete this exception notice.
40 */
41\f
42
43#include <stdio.h>
44#include "_scm.h"
20e6290e
JB
45#include "pairs.h"
46#include "genio.h"
47#include "throw.h"
48
49#include "error.h"
0f2d19dd 50
95b88819
GH
51#ifdef HAVE_UNISTD_H
52#include <unistd.h>
53#endif
0f2d19dd
JB
54\f
55
56\f
57/* {Errors and Exceptional Conditions}
58 */
59
0f2d19dd
JB
60
61/* True between SCM_DEFER_INTS and SCM_ALLOW_INTS, and
62 * when the interpreter is not running at all.
63 */
64int scm_ints_disabled = 1;
65
0f2d19dd 66extern int errno;
f5bf2977 67
1cc91f1b
JB
68static void err_head SCM_P ((char *str));
69
0f2d19dd
JB
70static void
71err_head (str)
72 char *str;
0f2d19dd
JB
73{
74 int oerrno = errno;
75 if (SCM_NIMP (scm_cur_outp))
76 scm_fflush (scm_cur_outp);
77 scm_gen_putc ('\n', scm_cur_errp);
78#if 0
79 if (SCM_BOOL_F != *scm_loc_loadpath)
80 {
a25840f9 81 scm_prin1 (*scm_loc_loadpath, scm_cur_errp, 1);
0f2d19dd
JB
82 scm_gen_puts (scm_regular_string, ", line ", scm_cur_errp);
83 scm_intprint ((long) scm_linum, 10, scm_cur_errp);
84 scm_gen_puts (scm_regular_string, ": ", scm_cur_errp);
85 }
86#endif
87 scm_fflush (scm_cur_errp);
88 errno = oerrno;
89 if (scm_cur_errp == scm_def_errp)
90 {
91 if (errno > 0)
92 perror (str);
93 fflush (stderr);
94 return;
95 }
96}
97
98
99SCM_PROC(s_errno, "errno", 0, 1, 0, scm_errno);
f5bf2977 100SCM
0f2d19dd
JB
101scm_errno (arg)
102 SCM arg;
0f2d19dd
JB
103{
104 int old = errno;
105 if (!SCM_UNBNDP (arg))
106 {
107 if (SCM_FALSEP (arg))
108 errno = 0;
109 else
110 errno = SCM_INUM (arg);
111 }
112 return SCM_MAKINUM (old);
113}
114
115SCM_PROC(s_perror, "perror", 1, 0, 0, scm_perror);
0f2d19dd
JB
116SCM
117scm_perror (arg)
118 SCM arg;
0f2d19dd
JB
119{
120 SCM_ASSERT (SCM_NIMP (arg) && SCM_STRINGP (arg), arg, SCM_ARG1, s_perror);
121 err_head (SCM_CHARS (arg));
122 return SCM_UNSPECIFIED;
123}
124
7cb1d4d3 125void (*scm_error_callback) () = 0;
0f2d19dd 126
f5bf2977 127/* all errors thrown from C should pass through here. */
01f61221 128/* also known as scm_error. */
7cb1d4d3
GH
129void
130scm_error (key, subr, message, args, rest)
131 SCM key;
132 char *subr;
133 char *message;
134 SCM args;
135 SCM rest;
136{
137 SCM arg_list;
138 if (scm_error_callback)
139 (*scm_error_callback) (key, subr, message, args, rest);
140
f5bf2977 141 arg_list = scm_listify (subr ? scm_makfrom0str (subr) : SCM_BOOL_F,
b59b97ba 142 message ? scm_makfrom0str (message) : SCM_BOOL_F,
7cb1d4d3
GH
143 args,
144 rest,
145 SCM_UNDEFINED);
146 scm_ithrow (key, arg_list, 1);
147
148 /* No return, but just in case: */
149
150 write (2, "unhandled system error", sizeof ("unhandled system error") - 1);
151 exit (1);
152}
0f2d19dd 153
e1724d20
GH
154/* error keys: defined here, initialized below, prototyped in error.h,
155 associated with handler procedures in boot-9.scm. */
52859adf
GH
156SCM scm_system_error_key;
157SCM scm_num_overflow_key;
158SCM scm_out_of_range_key;
f5bf2977
GH
159SCM scm_arg_type_key;
160SCM scm_args_number_key;
161SCM scm_memory_alloc_key;
162SCM scm_stack_overflow_key;
163SCM scm_misc_error_key;
e1724d20 164
52859adf
GH
165void
166scm_syserror (subr)
167 char *subr;
168{
01f61221 169 scm_error (scm_system_error_key,
52859adf 170 subr,
f5bf2977 171 "%s",
52859adf
GH
172 scm_listify (scm_makfrom0str (strerror (errno)),
173 SCM_UNDEFINED),
174 scm_listify (SCM_MAKINUM (errno), SCM_UNDEFINED));
175}
176
177void
178scm_syserror_msg (subr, message, args)
179 char *subr;
180 char *message;
181 SCM args;
182{
01f61221 183 scm_error (scm_system_error_key,
52859adf
GH
184 subr,
185 message,
186 args,
187 scm_listify (SCM_MAKINUM (errno), SCM_UNDEFINED));
188}
189
190void
191scm_sysmissing (subr)
192 char *subr;
193{
194#ifdef ENOSYS
01f61221 195 scm_error (scm_system_error_key,
52859adf 196 subr,
f5bf2977 197 "%s",
52859adf
GH
198 scm_listify (scm_makfrom0str (strerror (ENOSYS)), SCM_UNDEFINED),
199 scm_listify (SCM_MAKINUM (ENOSYS), SCM_UNDEFINED));
200#else
01f61221 201 scm_error (scm_system_error_key,
52859adf
GH
202 subr,
203 "Missing function",
204 SCM_BOOL_F,
205 scm_listify (SCM_MAKINUM (0), SCM_UNDEFINED));
206#endif
207}
208
209void
210scm_num_overflow (subr)
211 char *subr;
212{
01f61221 213 scm_error (scm_num_overflow_key,
52859adf
GH
214 subr,
215 "Numerical overflow",
216 SCM_BOOL_F,
217 SCM_BOOL_F);
218}
219
220void
221scm_out_of_range (subr, bad_value)
222 char *subr;
223 SCM bad_value;
224{
01f61221 225 scm_error (scm_out_of_range_key,
52859adf
GH
226 subr,
227 "Argument out of range: %S",
228 scm_listify (bad_value, SCM_UNDEFINED),
229 SCM_BOOL_F);
230}
f5bf2977 231
0f2d19dd 232void
f5bf2977
GH
233scm_wrong_num_args (proc)
234 SCM proc;
235{
01f61221 236 scm_error (scm_args_number_key,
f5bf2977
GH
237 NULL,
238 "Wrong number of arguments to %s",
239 scm_listify (proc, SCM_UNDEFINED),
240 SCM_BOOL_F);
241}
242
243void
244scm_wrong_type_arg (subr, pos, bad_value)
245 char *subr;
246 int pos;
247 SCM bad_value;
248{
01f61221 249 scm_error (scm_arg_type_key,
f5bf2977
GH
250 subr,
251 (pos == 0) ? "Wrong type argument: %S"
252 : "Wrong type argument in position %s: %S",
253 (pos == 0) ? scm_listify (bad_value, SCM_UNDEFINED)
254 : scm_listify (SCM_MAKINUM (pos), bad_value, SCM_UNDEFINED),
255 SCM_BOOL_F);
256}
257
258void
259scm_memory_error (subr)
260 char *subr;
261{
01f61221 262 scm_error (scm_memory_alloc_key,
f5bf2977
GH
263 subr,
264 "Memory allocation error",
265 SCM_BOOL_F,
266 SCM_BOOL_F);
267}
268
269/* implements the SCM_ASSERT interface. */
270SCM
271scm_wta (arg, pos, s_subr)
272 SCM arg;
273 char *pos;
274 char *s_subr;
275{
276 if (!s_subr || !*s_subr)
277 s_subr = NULL;
278 if ((~0x1fL) & (long) pos)
279 {
280 /* error string supplied. */
01f61221 281 scm_error (scm_misc_error_key,
f5bf2977
GH
282 s_subr,
283 pos,
284 SCM_BOOL_F,
285 SCM_BOOL_F);
286 }
287 else
288 {
289 /* numerical error code. */
290 int error = (long) pos;
291
292 switch (error)
293 {
294 case SCM_ARGn:
295 scm_wrong_type_arg (s_subr, 0, arg);
296 case SCM_ARG1:
297 scm_wrong_type_arg (s_subr, 1, arg);
298 case SCM_ARG2:
299 scm_wrong_type_arg (s_subr, 2, arg);
300 case SCM_ARG3:
301 scm_wrong_type_arg (s_subr, 3, arg);
302 case SCM_ARG4:
303 scm_wrong_type_arg (s_subr, 4, arg);
304 case SCM_ARG5:
305 scm_wrong_type_arg (s_subr, 5, arg);
306 case SCM_WNA:
307 scm_wrong_num_args (arg);
308 case SCM_OUTOFRANGE:
309 scm_out_of_range (s_subr, arg);
310 case SCM_NALLOC:
311 scm_memory_error (s_subr);
312 default:
313 /* this shouldn't happen. */
01f61221 314 scm_error (scm_misc_error_key,
f5bf2977
GH
315 s_subr,
316 "Unknown error",
317 SCM_BOOL_F,
318 SCM_BOOL_F);
319 }
320 }
321 return SCM_UNSPECIFIED;
322}
323
324/* obsolete interface: scm_everr (exp, env, arg, pos, s_subr)
325 was equivalent to scm_wta (arg, pos, s_subr) */
326
0f2d19dd
JB
327void
328scm_init_error ()
0f2d19dd 329{
52859adf 330 scm_system_error_key
e1724d20 331 = scm_permanent_object (SCM_CAR (scm_intern0 ("system-error")));
52859adf 332 scm_num_overflow_key
e1724d20 333 = scm_permanent_object (SCM_CAR (scm_intern0 ("numerical-overflow")));
52859adf
GH
334 scm_out_of_range_key
335 = scm_permanent_object (SCM_CAR (scm_intern0 ("out-of-range")));
f5bf2977
GH
336 scm_arg_type_key
337 = scm_permanent_object (SCM_CAR (scm_intern0 ("wrong-type-arg")));
338 scm_args_number_key
339 = scm_permanent_object (SCM_CAR (scm_intern0 ("wrong-number-of-args")));
340 scm_memory_alloc_key
341 = scm_permanent_object (SCM_CAR (scm_intern0 ("memory-allocation-error")));
342 scm_stack_overflow_key
343 = scm_permanent_object (SCM_CAR (scm_intern0 ("stack-overflow")));
344 scm_misc_error_key
345 = scm_permanent_object (SCM_CAR (scm_intern0 ("misc-error")));
0f2d19dd
JB
346#include "error.x"
347}
348