chiark / gitweb /
@@@ tty mess
[mLib] / utils / exc.3.in
1 .\" -*-nroff-*-
2 .\"
3 .\" Manual for exception handling
4 .\"
5 .\" (c) 1999, 2001, 2005, 2009, 2024 Straylight/Edgeware
6 .\"
7 .
8 .\"----- Licensing notice ---------------------------------------------------
9 .\"
10 .\" This file is part of the mLib utilities library.
11 .\"
12 .\" mLib is free software: you can redistribute it and/or modify it under
13 .\" the terms of the GNU Library General Public License as published by
14 .\" the Free Software Foundation; either version 2 of the License, or (at
15 .\" your option) any later version.
16 .\"
17 .\" mLib is distributed in the hope that it will be useful, but WITHOUT
18 .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 .\" FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
20 .\" License for more details.
21 .\"
22 .\" You should have received a copy of the GNU Library General Public
23 .\" License along with mLib.  If not, write to the Free Software
24 .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 .\" USA.
26 .
27 .\"--------------------------------------------------------------------------
28 .so ../defs.man \" @@@PRE@@@
29 .
30 .\"--------------------------------------------------------------------------
31 .TH exc 3mLib "20 June 1999" "Straylight/Edgeware" "mLib utilities library"
32 .\" @TRY
33 .\" @CATCH
34 .\" @END_TRY
35 .\" @THROW
36 .\" @RETHROW
37 .
38 .\" @exc_uncaught
39 .
40 .\" @EXC_PAIR
41 .\" @EXC_ALLOC
42 .\" @EXC_ALLOCN
43 .\" @EXC_ALLOCI
44 .\" @EXC_ALLOCP
45 .\" @EXC_ALLOCS
46 .
47 .\"--------------------------------------------------------------------------
48 .SH NAME
49 exc \- exception handling for C programs
50 .
51 .\"--------------------------------------------------------------------------
52 .SH SYNOPSIS
53 .
54 .nf
55 .B "#include <mLib/exc.h>"
56 .PP
57 .ta 2n
58 .B TRY
59 .I "    statement"
60 .B CATCH
61 .I "    statement"
62 .B END_TRY;
63 .B EXIT_TRY;
64 .PP
65 .BI "THROW(exc_extype " type " " "" \fR[ "" ", "data \fR] "" );
66 .B RETHROW;
67 .PP
68 .nf
69 .B "typedef void (*exc__uncaught)(exc_extype, exc_exval);"
70 .BI "exc__uncaught exc_uncaught(exc__uncaught " proc );
71 .PP
72 .BI "exc_extype EXC_PAIR(unsigned char " x ", unsigned char " y );
73 .BI "exc_extype EXC_ALLOC(exc_extype " owner ", exc_extype " type );
74 .BI "exc_extype EXC_ALLOCN(exc_extype " owner ", exc_extype " type );
75 .BI "exc_extype EXC_ALLOCI(exc_extype " owner ", exc_extype " type );
76 .BI "exc_extype EXC_ALLOCP(exc_extype " owner ", exc_extype " type );
77 .BI "exc_extype EXC_ALLOCS(exc_extype " owner ", exc_extype " type );
78 .fi
79 .
80 .\"--------------------------------------------------------------------------
81 .SH DESCRIPTION
82 .
83 The header file
84 .B <mLib/exc.h>
85 introduces some new syntax and definitions to support exception handling
86 in C.  The marriage is not particularly successful, although it works
87 well enough in practice.
88 .PP
89 The syntax introduced consists of new
90 .B TRY
91 and
92 .B EXIT_TRY
93 statements and a pair of new expression types
94 .B THROW
95 and
96 .BR RETHROW .
97 It's unfortunately important to remember that the syntax is provided
98 using macro expansion and standard C facilities; some of the
99 restrictions of these features show through.
100 .
101 .SS "The TRY statement"
102 The
103 .B TRY
104 statement associates an exception handler with a piece of code.  The
105 second statement is an
106 .IR "exception handler" .
107 Its
108 .I "dynamic scope"
109 is the duration of the first statement's execution, together with the
110 duration of any functions called within the dynamic scope.  (Note in
111 particular that an exception handler is not within its own dynamic
112 scope.)  A thrown exception causes the exception handler with
113 dynamically innermost scope to be executed.
114 .PP
115 Two special variables are provided to the exception handler:
116 .TP
117 .B exc_type
118 The
119 .I type
120 of the exception caught.  This is value of type
121 .B exc_extype
122 (described below).
123 .TP
124 .B exc_val
125 The
126 .I value
127 of the exception.  This has a union type, with members
128 .BR "int i",
129 .B "void *p"
130 and
131 .BR "char *s" .
132 Only one of the members is valid; you should be able to work out which
133 from the exception type.  There are abbreviations
134 .BR "exc_i",
135 .B exc_p
136 and
137 .B exc_s
138 which refer to members of
139 .B exc_val
140 directly.
141 .
142 .SS "The EXIT_TRY statement"
143 It is not safe to leave the dynamic scope of an exception handler early
144 (e.g., by a
145 .B goto
146 statement).  You can force a safe exit from a dynamic scope using the
147 .B EXIT_TRY
148 statement from within the
149 .I lexical
150 scope of the
151 .B TRY
152 statement.
153 .
154 .SS "The THROW and RETHROW statements"
155 The
156 .B THROW
157 expression throws an exception.  The first argument is the type of
158 exception; the second is some data to attach to the exception.  The type
159 of data, integer, string or pointer, is determined from the exception
160 type.
161 .PP
162 Control is immediately passed to the exception handler with the
163 innermost enclosing dynamic scope.
164 .PP
165 The
166 .B RETHROW
167 expression is only valid within an exception handler.  It rethrows the
168 last exception caught by the handler.
169 .PP
170 Neither
171 .B THROW
172 nor
173 .B RETHROW
174 yields any value.
175 .
176 .SS "Exception type allocation"
177 Exception types are 32-bit values.  The top 16 bits are an
178 .IR "owner identifier" .
179 The idea is that each library can have an owner identifier, and it can
180 then allocate exceptions for its own use from the remaining space.  Two
181 special owner codes are defined:
182 .TP
183 .B "EXC_GLOBAL (0x0000)"
184 The global space defined for everyone's benefit.  Don't define your own
185 exceptions in this space.
186 .TP
187 .B "EXC_SHARED (0xffff)"
188 A shared space.  You can use this for any exceptions which won't be seen
189 by anyone else.
190 .PP
191 Other owner codes may be allocated by choosing two characters (probably
192 letters) which best suit your application and applying the
193 .B EXC_PAIR
194 macro to them.  For example, the owner code for
195 .B mLib
196 would probably be
197 .BR "EXC_PAIR('m', 'L')" ,
198 if
199 .B mLib
200 defined any exceptions other then the global ones.
201 .PP
202 The bottom 16 bits are the actual exception type, and the data type
203 which gets passed around with the exception.  The data type is
204 (bizarrely) in bits 6 and 7 of the type word.  The data type code is one
205 of the following:
206 .TP
207 .B EXC_NOVAL
208 There is no data associated with this exception.
209 .TP
210 .B EXC_INTVAL
211 The data is an integer, with type
212 .BR int .
213 .TP
214 .B EXC_PTRVAL
215 The data is a pointer to some data structure, with type
216 .BR "void *" .
217 Note that you probably have to do an explicit cast to
218 .B "void *"
219 in the
220 .B THROW
221 expression.
222 .TP
223 .B EXC_STRVAL
224 The data is a pointer to a string of characters, of type
225 .BR "char *" .
226 .PP
227 If the data to be thrown is a pointer, make sure that the object pointed
228 to has a long enough lifetime for it to actually get to its exception
229 handler intact.  In particular, don't pass pointers to automatic
230 variables unless you're
231 .I sure
232 they were allocated outside the handler's dynamic scope.
233 .PP
234 Individual exceptions are allocated by the macros
235 .BI EXC_ALLOC t\fR,
236 where
237 .I t
238 is one of:
239 .TP
240 .B N
241 The exception has no data
242 .TP
243 .B I
244 The exception data is an integer.
245 .TP
246 .B P
247 The exception data is a pointer.
248 .TP
249 .B S
250 The exception data is a character string.
251 .PP
252 The
253 .BI EXC_ALLOC t
254 macros take two arguments: the owner code (usually allocated with
255 .B EXC_PAIR
256 as described above), and the type code.  The data type is encoded into
257 the exception type by the allocation macro.
258 .
259 .SS "Predefined exceptions"
260 The following exceptions are predefined:
261 .TP
262 .B EXC_NOMEM
263 No data.  Signals an out-of-memory condition.
264 .TP
265 .B EXC_ERRNO
266 Integer data.  Signals an operating system error.  The data is the value
267 of
268 .B errno
269 associated with the error.
270 .TP
271 .B EXC_OSERROR
272 Pointer data.  Signals a RISC\ OS error.  The data is a pointer to the
273 RISC\ OS error block.  (Non RISC\ OS programmers don't need to worry
274 about this.)
275 .TP
276 .B EXC_SIGNAL
277 Integer data.  Signals a raised operating system signal.  The data is
278 the signal number.
279 .TP
280 .B EXC_FAIL
281 String data.  Signals a miscellaneous failure.  The data is a pointer to
282 an explanatory string.
283 .SH BUGS
284 The call to an exception handler is achieved using
285 .BR longjmp (3).
286 Therefore all the caveats about
287 .B longjmp
288 and automatic data apply.  Also, note that status such as the signal
289 mask is not reset, so you might have to do that manually in order to
290 recover from a signal.
291 .
292 .\"--------------------------------------------------------------------------
293 .SH "SEE ALSO"
294 .
295 .BR mLib (3).
296 .
297 .\"--------------------------------------------------------------------------
298 .SH AUTHOR
299 .
300 Mark Wooding, <mdw@distorted.org.uk>
301 .
302 .\"----- That's all, folks --------------------------------------------------