Commit | Line | Data |
---|---|---|
b6b9d458 | 1 | .\" -*-nroff-*- |
c4ccbbf9 MW |
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" | |
08da152e | 32 | .\" @TRY |
33 | .\" @CATCH | |
34 | .\" @END_TRY | |
35 | .\" @THROW | |
36 | .\" @RETHROW | |
c4ccbbf9 | 37 | . |
d2a91066 | 38 | .\" @exc_uncaught |
c4ccbbf9 | 39 | . |
08da152e | 40 | .\" @EXC_PAIR |
41 | .\" @EXC_ALLOC | |
42 | .\" @EXC_ALLOCN | |
43 | .\" @EXC_ALLOCI | |
44 | .\" @EXC_ALLOCP | |
45 | .\" @EXC_ALLOCS | |
c4ccbbf9 MW |
46 | . |
47 | .\"-------------------------------------------------------------------------- | |
48 | .SH NAME | |
49 | exc \- exception handling for C programs | |
50 | . | |
51 | .\"-------------------------------------------------------------------------- | |
b6b9d458 | 52 | .SH SYNOPSIS |
c4ccbbf9 MW |
53 | . |
54 | .nf | |
d2a91066 | 55 | .B "#include <mLib/exc.h>" |
c4ccbbf9 MW |
56 | .PP |
57 | .ta 2n | |
b6b9d458 | 58 | .B TRY |
c4ccbbf9 | 59 | .I " statement" |
b6b9d458 | 60 | .B CATCH |
c4ccbbf9 | 61 | .I " statement" |
b6b9d458 | 62 | .B END_TRY; |
b6b9d458 | 63 | .B EXIT_TRY; |
c4ccbbf9 MW |
64 | .PP |
65 | .BI "THROW(exc_extype " type " " "" \fR[ "" ", "data \fR] "" ); | |
b6b9d458 | 66 | .B RETHROW; |
c4ccbbf9 | 67 | .PP |
b6b9d458 | 68 | .nf |
69 | .B "typedef void (*exc__uncaught)(exc_extype, exc_exval);" | |
70 | .BI "exc__uncaught exc_uncaught(exc__uncaught " proc ); | |
d056fbdf | 71 | .PP |
b6b9d458 | 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 | |
c4ccbbf9 MW |
79 | . |
80 | .\"-------------------------------------------------------------------------- | |
b6b9d458 | 81 | .SH DESCRIPTION |
c4ccbbf9 | 82 | . |
b6b9d458 | 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. | |
c4ccbbf9 | 100 | . |
b6b9d458 | 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. | |
c4ccbbf9 | 141 | . |
b6b9d458 | 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. | |
c4ccbbf9 | 153 | . |
b6b9d458 | 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. | |
c4ccbbf9 | 175 | . |
b6b9d458 | 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. | |
c4ccbbf9 | 258 | . |
b6b9d458 | 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 | |
d2a91066 | 284 | The call to an exception handler is achieved using |
b6b9d458 | 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. | |
c4ccbbf9 MW |
291 | . |
292 | .\"-------------------------------------------------------------------------- | |
08da152e | 293 | .SH "SEE ALSO" |
c4ccbbf9 | 294 | . |
08da152e | 295 | .BR mLib (3). |
c4ccbbf9 MW |
296 | . |
297 | .\"-------------------------------------------------------------------------- | |
b6b9d458 | 298 | .SH AUTHOR |
c4ccbbf9 | 299 | . |
9b5ac6ff | 300 | Mark Wooding, <mdw@distorted.org.uk> |
c4ccbbf9 MW |
301 | . |
302 | .\"----- That's all, folks -------------------------------------------------- |