chiark / gitweb /
Initial revision
[ssr] / StraySrc / Libraries / Steel / c / exception
1 /*
2  * Exception
3  *  Handles odd errors in Steel programs
4  *
5  * 1.00 (24 September 1993)
6  *
7  * © 1993-1998 Straylight
8  */
9
10 /*----- Licensing note ----------------------------------------------------*
11  *
12  * This file is part of Straylight's Steel library.
13  *
14  * Steel is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2, or (at your option)
17  * any later version.
18  *
19  * Steel is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with Steel.  If not, write to the Free Software Foundation,
26  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include "msgs.h"
33 #include "exception.h"
34 #include "wimpt.h"
35 #include "werr.h"
36 #include "visdelay.h"
37
38 #ifndef BOOL
39 #define BOOL int
40 #define TRUE 1
41 #define FALSE 0
42 #endif
43
44 static BOOL exception__handled;
45 static int *exception__handler;
46
47 /*
48  * int exception_registerHandler(exception_handler env)
49  *
50  * Use
51  *  Registers the current point as being a sensible place to go after an
52  *  exception.  This is implemented as a macro for the simple reason that
53  *  things tend to go a tad wrong if you define your exception_handlers in a
54  *  function and then return.
55  *
56  * Parameters
57  *  exception_handler env == an undefined variable of the type
58  *    exception_handler.
59  */
60
61 #ifndef exception_registerHandler
62 #define exception_registerHandler(env) \
63   (exception__registerHandler((env),setjmp(env)))
64 #endif
65
66 /*
67  * void exception_generate(char *message,...)
68  *
69  * Use
70  *  Generates a Steel exception, to be handled in an appropriate manner.
71  *
72  * Parameters
73  *  char *message == printf()-type format string
74  */
75
76 void exception_generate(char *message,...)
77 {
78   char buffer[256];
79   va_list ap;
80   va_start(ap,message);
81   vsprintf(buffer,message,ap);
82   va_end(ap);
83   visdelay_suspend(); /* It doesn't mind if we suspend indefinitely */
84   if (exception__handled==FALSE)
85   {
86     werr(FALSE,msgs_lookup("excFATAL:Fatal internal error: '%s'"),buffer);
87     exit(1);
88   }
89   else
90   {
91     if (werr_error((wimpt_options() & wimpt_ONOBACKTRACE) ? 2 : 3,
92                    msgs_lookup("excSEV:Internal error: '%s'.  Click OK "
93                                "to continue, or Cancel to quit %s."),
94                    buffer,
95                    wimpt_programname())==0)
96     {
97       if (werr_error(2,
98                      msgs_lookup("excAYS:Are you sure you want to quit %s?  "
99                                  "Click OK to continue, or Cancel to quit."),
100                      wimpt_programname())==0)
101       {
102         exit(1);
103       }
104       else
105         longjmp(exception__handler,1);
106     }
107     else
108       longjmp(exception__handler,1);
109   }
110 }
111
112 /*
113  * int exception__registerHandler(jmp_buf handler)
114  *
115  * Use
116  *  This routine is for the use of exception segment only, and should not be
117  *  called from your code.
118  */
119
120 int exception__registerHandler(jmp_buf handler,int result)
121 {
122   if (result==0)
123   {
124     exception__handled=TRUE;
125     exception__handler=handler;
126   }
127   return (result);
128 }