]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/guile/scm-exception.c
gdb, gdbserver, gdbsupport: remove includes of early headers
[thirdparty/binutils-gdb.git] / gdb / guile / scm-exception.c
CommitLineData
ed3ef339
DE
1/* GDB/Scheme exception support.
2
1d506c26 3 Copyright (C) 2014-2024 Free Software Foundation, Inc.
ed3ef339
DE
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20/* See README file in this directory for implementation notes, coding
21 conventions, et.al. */
22
23/* Notes:
24
25 IWBN to support SRFI 34/35. At the moment we follow Guile's own
26 exception mechanism.
27
28 The non-static functions in this file have prefix gdbscm_ and
29 not exscm_ on purpose. */
30
ed3ef339 31#include <signal.h>
ed3ef339
DE
32#include "guile-internal.h"
33
34/* The <gdb:exception> smob.
35 This is used to record and handle Scheme exceptions.
36 One important invariant is that <gdb:exception> smobs are never a valid
37 result of a function, other than to signify an exception occurred. */
38
f99b5177 39struct exception_smob
ed3ef339
DE
40{
41 /* This always appears first. */
42 gdb_smob base;
43
44 /* The key and args parameters to "throw". */
45 SCM key;
46 SCM args;
f99b5177 47};
ed3ef339
DE
48
49static const char exception_smob_name[] = "gdb:exception";
50
51/* The tag Guile knows the exception smob by. */
52static scm_t_bits exception_smob_tag;
53
54/* A generic error in struct gdb_exception.
55 I.e., not RETURN_QUIT and not MEMORY_ERROR. */
56static SCM error_symbol;
57
58/* An error occurred accessing inferior memory.
59 This is not a Scheme programming error. */
60static SCM memory_error_symbol;
61
62/* User interrupt, e.g., RETURN_QUIT in struct gdb_exception. */
63static SCM signal_symbol;
64
e698b8c4
DE
65/* A user error, e.g., bad arg to gdb command. */
66static SCM user_error_symbol;
67
ed3ef339
DE
68/* Printing the stack is done by first capturing the stack and recording it in
69 a <gdb:exception> object with this key and with the ARGS field set to
70 (cons real-key (cons stack real-args)).
71 See gdbscm_make_exception_with_stack. */
72static SCM with_stack_error_symbol;
73
74/* The key to use for an invalid object exception. An invalid object is one
75 where the underlying object has been removed from GDB. */
76SCM gdbscm_invalid_object_error_symbol;
77
78/* Values for "guile print-stack" as symbols. */
79static SCM none_symbol;
80static SCM message_symbol;
81static SCM full_symbol;
82
83static const char percent_print_exception_message_name[] =
84 "%print-exception-message";
85
86/* Variable containing %print-exception-message.
87 It is not defined until late in initialization, after our init routine
88 has run. Cope by looking it up lazily. */
89static SCM percent_print_exception_message_var = SCM_BOOL_F;
90
91static const char percent_print_exception_with_stack_name[] =
92 "%print-exception-with-stack";
93
94/* Variable containing %print-exception-with-stack.
95 It is not defined until late in initialization, after our init routine
96 has run. Cope by looking it up lazily. */
97static SCM percent_print_exception_with_stack_var = SCM_BOOL_F;
98
99/* Counter to keep track of the number of times we create a <gdb:exception>
100 object, for performance monitoring purposes. */
101static unsigned long gdbscm_exception_count = 0;
102\f
103/* Administrivia for exception smobs. */
104
ed3ef339
DE
105/* The smob "print" function for <gdb:exception>. */
106
107static int
108exscm_print_exception_smob (SCM self, SCM port, scm_print_state *pstate)
109{
110 exception_smob *e_smob = (exception_smob *) SCM_SMOB_DATA (self);
111
112 gdbscm_printf (port, "#<%s ", exception_smob_name);
113 scm_write (e_smob->key, port);
114 scm_puts (" ", port);
115 scm_write (e_smob->args, port);
116 scm_puts (">", port);
117
118 scm_remember_upto_here_1 (self);
119
120 /* Non-zero means success. */
121 return 1;
122}
123
124/* (make-exception key args) -> <gdb:exception> */
125
126SCM
127gdbscm_make_exception (SCM key, SCM args)
128{
129 exception_smob *e_smob = (exception_smob *)
130 scm_gc_malloc (sizeof (exception_smob), exception_smob_name);
131 SCM smob;
132
133 e_smob->key = key;
134 e_smob->args = args;
135 smob = scm_new_smob (exception_smob_tag, (scm_t_bits) e_smob);
136 gdbscm_init_gsmob (&e_smob->base);
137
138 ++gdbscm_exception_count;
139
140 return smob;
141}
142
143/* Return non-zero if SCM is a <gdb:exception> object. */
144
145int
146gdbscm_is_exception (SCM scm)
147{
148 return SCM_SMOB_PREDICATE (exception_smob_tag, scm);
149}
150
151/* (exception? scm) -> boolean */
152
153static SCM
154gdbscm_exception_p (SCM scm)
155{
156 return scm_from_bool (gdbscm_is_exception (scm));
157}
158
159/* (exception-key <gdb:exception>) -> key */
160
161SCM
162gdbscm_exception_key (SCM self)
163{
164 exception_smob *e_smob;
165
166 SCM_ASSERT_TYPE (gdbscm_is_exception (self), self, SCM_ARG1, FUNC_NAME,
167 "gdb:exception");
168
169 e_smob = (exception_smob *) SCM_SMOB_DATA (self);
170 return e_smob->key;
171}
172
173/* (exception-args <gdb:exception>) -> arg-list */
174
175SCM
176gdbscm_exception_args (SCM self)
177{
178 exception_smob *e_smob;
179
180 SCM_ASSERT_TYPE (gdbscm_is_exception (self), self, SCM_ARG1, FUNC_NAME,
181 "gdb:exception");
182
183 e_smob = (exception_smob *) SCM_SMOB_DATA (self);
184 return e_smob->args;
185}
186\f
187/* Wrap an exception in a <gdb:exception> object that includes STACK.
188 gdbscm_print_exception_with_stack knows how to unwrap it. */
189
190SCM
191gdbscm_make_exception_with_stack (SCM key, SCM args, SCM stack)
192{
193 return gdbscm_make_exception (with_stack_error_symbol,
194 scm_cons (key, scm_cons (stack, args)));
195}
196
197/* Version of scm_error_scm that creates a gdb:exception object that can later
198 be passed to gdbscm_throw.
199 KEY is a symbol denoting the kind of error.
200 SUBR is either #f or a string marking the function in which the error
201 occurred.
202 MESSAGE is either #f or the error message string. It may contain ~a and ~s
203 modifiers, provided by ARGS.
204 ARGS is a list of args to MESSAGE.
205 DATA is an arbitrary object, its value depends on KEY. The value to pass
206 here is a bit underspecified by Guile. */
207
208SCM
209gdbscm_make_error_scm (SCM key, SCM subr, SCM message, SCM args, SCM data)
210{
211 return gdbscm_make_exception (key, scm_list_4 (subr, message, args, data));
212}
213
214/* Version of scm_error that creates a gdb:exception object that can later
215 be passed to gdbscm_throw.
216 See gdbscm_make_error_scm for a description of the arguments. */
217
218SCM
219gdbscm_make_error (SCM key, const char *subr, const char *message,
220 SCM args, SCM data)
221{
222 return gdbscm_make_error_scm
223 (key,
224 subr == NULL ? SCM_BOOL_F : scm_from_latin1_string (subr),
225 message == NULL ? SCM_BOOL_F : scm_from_latin1_string (message),
226 args, data);
227}
228
229/* Version of SCM_ASSERT_TYPE/scm_wrong_type_arg_msg that creates a
230 gdb:exception object that can later be passed to gdbscm_throw. */
231
232SCM
233gdbscm_make_type_error (const char *subr, int arg_pos, SCM bad_value,
234 const char *expected_type)
235{
8579fd13 236 gdb::unique_xmalloc_ptr<char> msg;
ed3ef339
DE
237 SCM result;
238
239 if (arg_pos > 0)
240 {
241 if (expected_type != NULL)
242 {
243 msg = xstrprintf (_("Wrong type argument in position %d"
244 " (expecting %s): ~S"),
245 arg_pos, expected_type);
246 }
247 else
248 {
249 msg = xstrprintf (_("Wrong type argument in position %d: ~S"),
250 arg_pos);
251 }
252 }
253 else
254 {
255 if (expected_type != NULL)
256 {
257 msg = xstrprintf (_("Wrong type argument (expecting %s): ~S"),
258 expected_type);
259 }
260 else
261 msg = xstrprintf (_("Wrong type argument: ~S"));
262 }
263
8579fd13 264 result = gdbscm_make_error (scm_arg_type_key, subr, msg.get (),
ed3ef339 265 scm_list_1 (bad_value), scm_list_1 (bad_value));
ed3ef339
DE
266 return result;
267}
268
269/* A variant of gdbscm_make_type_error for non-type argument errors.
270 ERROR_PREFIX and ERROR are combined to build the error message.
271 Care needs to be taken so that the i18n composed form is still
272 reasonable, but no one is going to translate these anyway so we don't
273 worry too much.
274 ERROR_PREFIX may be NULL, ERROR may not be NULL. */
275
276static SCM
277gdbscm_make_arg_error (SCM key, const char *subr, int arg_pos, SCM bad_value,
278 const char *error_prefix, const char *error)
279{
8579fd13 280 gdb::unique_xmalloc_ptr<char> msg;
ed3ef339
DE
281 SCM result;
282
283 if (error_prefix != NULL)
284 {
285 if (arg_pos > 0)
286 {
287 msg = xstrprintf (_("%s %s in position %d: ~S"),
288 error_prefix, error, arg_pos);
289 }
290 else
291 msg = xstrprintf (_("%s %s: ~S"), error_prefix, error);
292 }
293 else
294 {
295 if (arg_pos > 0)
296 msg = xstrprintf (_("%s in position %d: ~S"), error, arg_pos);
297 else
298 msg = xstrprintf (_("%s: ~S"), error);
299 }
300
8579fd13
AB
301 result = gdbscm_make_error (key, subr, msg.get (), scm_list_1 (bad_value),
302 scm_list_1 (bad_value));
ed3ef339
DE
303 return result;
304}
305
306/* Make an invalid-object error <gdb:exception> object.
307 OBJECT is the name of the kind of object that is invalid. */
308
309SCM
310gdbscm_make_invalid_object_error (const char *subr, int arg_pos, SCM bad_value,
311 const char *object)
312{
313 return gdbscm_make_arg_error (gdbscm_invalid_object_error_symbol,
314 subr, arg_pos, bad_value,
315 _("Invalid object:"), object);
316}
317
318/* Throw an invalid-object error.
319 OBJECT is the name of the kind of object that is invalid. */
320
4a2722c5 321void
ed3ef339
DE
322gdbscm_invalid_object_error (const char *subr, int arg_pos, SCM bad_value,
323 const char *object)
324{
325 SCM exception
326 = gdbscm_make_invalid_object_error (subr, arg_pos, bad_value, object);
327
328 gdbscm_throw (exception);
329}
330
331/* Make an out-of-range error <gdb:exception> object. */
332
333SCM
334gdbscm_make_out_of_range_error (const char *subr, int arg_pos, SCM bad_value,
335 const char *error)
336{
337 return gdbscm_make_arg_error (scm_out_of_range_key,
338 subr, arg_pos, bad_value,
339 _("Out of range:"), error);
340}
341
342/* Throw an out-of-range error.
343 This is the standard Guile out-of-range exception. */
344
4a2722c5 345void
ed3ef339
DE
346gdbscm_out_of_range_error (const char *subr, int arg_pos, SCM bad_value,
347 const char *error)
348{
349 SCM exception
350 = gdbscm_make_out_of_range_error (subr, arg_pos, bad_value, error);
351
352 gdbscm_throw (exception);
353}
354
355/* Make a misc-error <gdb:exception> object. */
356
357SCM
358gdbscm_make_misc_error (const char *subr, int arg_pos, SCM bad_value,
06eb1586 359 const char *error)
ed3ef339
DE
360{
361 return gdbscm_make_arg_error (scm_misc_error_key,
362 subr, arg_pos, bad_value, NULL, error);
363}
364
06eb1586
DE
365/* Throw a misc-error error. */
366
367void
368gdbscm_misc_error (const char *subr, int arg_pos, SCM bad_value,
369 const char *error)
370{
371 SCM exception = gdbscm_make_misc_error (subr, arg_pos, bad_value, error);
372
373 gdbscm_throw (exception);
374}
375
ed3ef339
DE
376/* Return a <gdb:exception> object for gdb:memory-error. */
377
378SCM
379gdbscm_make_memory_error (const char *subr, const char *msg, SCM args)
380{
381 return gdbscm_make_error (memory_error_symbol, subr, msg, args,
382 SCM_EOL);
383}
384
385/* Throw a gdb:memory-error exception. */
386
4a2722c5 387void
ed3ef339
DE
388gdbscm_memory_error (const char *subr, const char *msg, SCM args)
389{
390 SCM exception = gdbscm_make_memory_error (subr, msg, args);
391
392 gdbscm_throw (exception);
393}
394
395/* Return non-zero if KEY is gdb:memory-error.
396 Note: This is an excp_matcher_func function. */
397
398int
399gdbscm_memory_error_p (SCM key)
400{
401 return scm_is_eq (key, memory_error_symbol);
402}
403
e698b8c4
DE
404/* Return non-zero if KEY is gdb:user-error.
405 Note: This is an excp_matcher_func function. */
406
407int
408gdbscm_user_error_p (SCM key)
409{
410 return scm_is_eq (key, user_error_symbol);
411}
412
ed3ef339
DE
413/* Wrapper around scm_throw to throw a gdb:exception.
414 This function does not return.
415 This function cannot be called from inside TRY_CATCH. */
416
417void
418gdbscm_throw (SCM exception)
419{
420 scm_throw (gdbscm_exception_key (exception),
421 gdbscm_exception_args (exception));
422 gdb_assert_not_reached ("scm_throw returned");
423}
424
425/* Convert a GDB exception to a <gdb:exception> object. */
426
427SCM
680d7fd5 428gdbscm_scm_from_gdb_exception (const gdbscm_gdb_exception &exception)
ed3ef339
DE
429{
430 SCM key;
431
432 if (exception.reason == RETURN_QUIT)
433 {
434 /* Handle this specially to be consistent with top-repl.scm. */
435 return gdbscm_make_error (signal_symbol, NULL, _("User interrupt"),
436 SCM_EOL, scm_list_1 (scm_from_int (SIGINT)));
437 }
438
439 if (exception.error == MEMORY_ERROR)
440 key = memory_error_symbol;
441 else
442 key = error_symbol;
443
444 return gdbscm_make_error (key, NULL, "~A",
445 scm_list_1 (gdbscm_scm_from_c_string
680d7fd5 446 (exception.message)),
ed3ef339
DE
447 SCM_BOOL_F);
448}
449
450/* Convert a GDB exception to the appropriate Scheme exception and throw it.
451 This function does not return. */
452
453void
680d7fd5 454gdbscm_throw_gdb_exception (gdbscm_gdb_exception exception)
ed3ef339 455{
680d7fd5
TT
456 SCM scm_exception = gdbscm_scm_from_gdb_exception (exception);
457 xfree (exception.message);
458 gdbscm_throw (scm_exception);
ed3ef339
DE
459}
460
461/* Print the error message portion of an exception.
462 If PORT is #f, use the standard error port.
463 KEY cannot be gdb:with-stack.
464
465 Basically this function is just a wrapper around calling
466 %print-exception-message. */
467
468static void
469gdbscm_print_exception_message (SCM port, SCM frame, SCM key, SCM args)
470{
471 SCM printer, status;
472
473 if (gdbscm_is_false (port))
474 port = scm_current_error_port ();
475
476 gdb_assert (!scm_is_eq (key, with_stack_error_symbol));
477
478 /* This does not use scm_print_exception because we tweak the output a bit.
479 Compare Guile's print-exception with our %print-exception-message for
480 details. */
481 if (gdbscm_is_false (percent_print_exception_message_var))
482 {
483 percent_print_exception_message_var
484 = scm_c_private_variable (gdbscm_init_module_name,
485 percent_print_exception_message_name);
486 /* If we can't find %print-exception-message, there's a problem on the
487 Scheme side. Don't kill GDB, just flag an error and leave it at
488 that. */
489 if (gdbscm_is_false (percent_print_exception_message_var))
490 {
491 gdbscm_printf (port, _("Error in Scheme exception printing,"
492 " can't find %s.\n"),
493 percent_print_exception_message_name);
494 return;
495 }
496 }
497 printer = scm_variable_ref (percent_print_exception_message_var);
498
499 status = gdbscm_safe_call_4 (printer, port, frame, key, args, NULL);
500
501 /* If that failed still tell the user something.
502 But don't use the exception printing machinery! */
503 if (gdbscm_is_exception (status))
504 {
505 gdbscm_printf (port, _("Error in Scheme exception printing:\n"));
506 scm_display (status, port);
507 scm_newline (port);
508 }
509}
510
511/* Print the description of exception KEY, ARGS to PORT, according to the
512 setting of "set guile print-stack".
513 If PORT is #f, use the standard error port.
514 If STACK is #f, never print the stack, regardless of whether printing it
515 is enabled. If STACK is #t, then print it if it is contained in ARGS
516 (i.e., KEY is gdb:with-stack). Otherwise STACK is the result of calling
517 scm_make_stack (which will be ignored in favor of the stack in ARGS if
518 KEY is gdb:with-stack).
519 KEY, ARGS are the standard arguments to scm_throw, et.al.
520
521 Basically this function is just a wrapper around calling
d2929fdc 522 %print-exception-with-stack. */
ed3ef339
DE
523
524void
525gdbscm_print_exception_with_stack (SCM port, SCM stack, SCM key, SCM args)
526{
527 SCM printer, status;
528
529 if (gdbscm_is_false (port))
530 port = scm_current_error_port ();
531
532 if (gdbscm_is_false (percent_print_exception_with_stack_var))
533 {
534 percent_print_exception_with_stack_var
535 = scm_c_private_variable (gdbscm_init_module_name,
536 percent_print_exception_with_stack_name);
d2929fdc 537 /* If we can't find %print-exception-with-stack, there's a problem on the
ed3ef339
DE
538 Scheme side. Don't kill GDB, just flag an error and leave it at
539 that. */
540 if (gdbscm_is_false (percent_print_exception_with_stack_var))
541 {
542 gdbscm_printf (port, _("Error in Scheme exception printing,"
543 " can't find %s.\n"),
544 percent_print_exception_with_stack_name);
545 return;
546 }
547 }
548 printer = scm_variable_ref (percent_print_exception_with_stack_var);
549
550 status = gdbscm_safe_call_4 (printer, port, stack, key, args, NULL);
551
552 /* If that failed still tell the user something.
553 But don't use the exception printing machinery! */
554 if (gdbscm_is_exception (status))
555 {
556 gdbscm_printf (port, _("Error in Scheme exception printing:\n"));
557 scm_display (status, port);
558 scm_newline (port);
559 }
560}
561
562/* Print EXCEPTION, a <gdb:exception> object, to PORT.
563 If PORT is #f, use the standard error port. */
564
565void
566gdbscm_print_gdb_exception (SCM port, SCM exception)
567{
568 gdb_assert (gdbscm_is_exception (exception));
569
570 gdbscm_print_exception_with_stack (port, SCM_BOOL_T,
571 gdbscm_exception_key (exception),
572 gdbscm_exception_args (exception));
573}
574
575/* Return a string description of <gdb:exception> EXCEPTION.
576 If EXCEPTION is a gdb:with-stack exception, unwrap it, a backtrace
15bf3002 577 is never returned as part of the result. */
ed3ef339 578
15bf3002 579gdb::unique_xmalloc_ptr<char>
ed3ef339
DE
580gdbscm_exception_message_to_string (SCM exception)
581{
582 SCM port = scm_open_output_string ();
583 SCM key, args;
ed3ef339
DE
584
585 gdb_assert (gdbscm_is_exception (exception));
586
587 key = gdbscm_exception_key (exception);
588 args = gdbscm_exception_args (exception);
589
590 if (scm_is_eq (key, with_stack_error_symbol)
591 /* Don't crash on a badly generated gdb:with-stack exception. */
592 && scm_is_pair (args)
593 && scm_is_pair (scm_cdr (args)))
594 {
595 key = scm_car (args);
596 args = scm_cddr (args);
597 }
598
599 gdbscm_print_exception_message (port, SCM_BOOL_F, key, args);
15bf3002 600 gdb::unique_xmalloc_ptr<char> result
4c693332 601 = gdbscm_scm_to_c_string (scm_get_output_string (port));
ed3ef339 602 scm_close_port (port);
ed3ef339
DE
603 return result;
604}
605
606/* Return the value of the "guile print-stack" option as one of:
607 'none, 'message, 'full. */
608
609static SCM
610gdbscm_percent_exception_print_style (void)
611{
612 if (gdbscm_print_excp == gdbscm_print_excp_none)
613 return none_symbol;
614 if (gdbscm_print_excp == gdbscm_print_excp_message)
615 return message_symbol;
616 if (gdbscm_print_excp == gdbscm_print_excp_full)
617 return full_symbol;
618 gdb_assert_not_reached ("bad value for \"guile print-stack\"");
619}
620
621/* Return the current <gdb:exception> counter.
622 This is for debugging purposes. */
623
624static SCM
625gdbscm_percent_exception_count (void)
626{
627 return scm_from_ulong (gdbscm_exception_count);
628}
629\f
630/* Initialize the Scheme exception support. */
631
632static const scheme_function exception_functions[] =
633{
72e02483 634 { "make-exception", 2, 0, 0, as_a_scm_t_subr (gdbscm_make_exception),
ed3ef339
DE
635 "\
636Create a <gdb:exception> object.\n\
637\n\
638 Arguments: key args\n\
639 These are the standard key,args arguments of \"throw\"." },
640
72e02483 641 { "exception?", 1, 0, 0, as_a_scm_t_subr (gdbscm_exception_p),
ed3ef339
DE
642 "\
643Return #t if the object is a <gdb:exception> object." },
644
72e02483 645 { "exception-key", 1, 0, 0, as_a_scm_t_subr (gdbscm_exception_key),
ed3ef339
DE
646 "\
647Return the exception's key." },
648
72e02483 649 { "exception-args", 1, 0, 0, as_a_scm_t_subr (gdbscm_exception_args),
ed3ef339
DE
650 "\
651Return the exception's arg list." },
652
653 END_FUNCTIONS
654};
655
656static const scheme_function private_exception_functions[] =
657{
72e02483
PA
658 { "%exception-print-style", 0, 0, 0,
659 as_a_scm_t_subr (gdbscm_percent_exception_print_style),
ed3ef339
DE
660 "\
661Return the value of the \"guile print-stack\" option." },
662
72e02483
PA
663 { "%exception-count", 0, 0, 0,
664 as_a_scm_t_subr (gdbscm_percent_exception_count),
ed3ef339
DE
665 "\
666Return a count of the number of <gdb:exception> objects created.\n\
667This is for debugging purposes." },
668
669 END_FUNCTIONS
670};
671
672void
673gdbscm_initialize_exceptions (void)
674{
675 exception_smob_tag = gdbscm_make_smob_type (exception_smob_name,
676 sizeof (exception_smob));
ed3ef339
DE
677 scm_set_smob_print (exception_smob_tag, exscm_print_exception_smob);
678
679 gdbscm_define_functions (exception_functions, 1);
680 gdbscm_define_functions (private_exception_functions, 0);
681
682 error_symbol = scm_from_latin1_symbol ("gdb:error");
683
684 memory_error_symbol = scm_from_latin1_symbol ("gdb:memory-error");
685
e698b8c4
DE
686 user_error_symbol = scm_from_latin1_symbol ("gdb:user-error");
687
ed3ef339
DE
688 gdbscm_invalid_object_error_symbol
689 = scm_from_latin1_symbol ("gdb:invalid-object-error");
690
691 with_stack_error_symbol = scm_from_latin1_symbol ("gdb:with-stack");
692
693 /* The text of this symbol is taken from Guile's top-repl.scm. */
694 signal_symbol = scm_from_latin1_symbol ("signal");
695
696 none_symbol = scm_from_latin1_symbol ("none");
697 message_symbol = scm_from_latin1_symbol ("message");
698 full_symbol = scm_from_latin1_symbol ("full");
699}