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