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