|
|
1.1 root 1: .TH EXCEPT 3 Stanford
2: .SH NAME
3: (except) raise, raise_sys() \- C exception handling
4: .SH SYNOPSIS
5: .B #include <xnscourier/except.h>
6: .sp
7: .B raise(code, msg)
8: .br
9: .B int code;
10: .br
11: .B char *msg;
12: .sp
13: .B raise_sys()
14: .sp
15: cc ... \-lexcept
16: .SH "EXTENDED C SYNTAX"
17: .B DURING
18: statement1
19: .B HANDLER
20: statement2
21: .B END_HANDLER
22: .sp
23: .B E_RETURN(
24: expression
25: .B )
26: .sp
27: .B E_RETURN_VOID
28: .SH DESCRIPTION
29: The macros and functions in this package provide a limited amount
30: of exception handling for programming in C. They provide the
31: ability to associate an exception handler to be invoked if an
32: exception is raised during the execution of a statement.
33: .PP
34: C syntax is extended by several macros that allow the programmer
35: to associate an exception handler with a statement. The ``syntax''
36: for this is:
37: .sp
38: .nf
39: DURING statement1 HANDLER statement2 END_HANDLER
40: .fi
41: .sp
42: Either or both statement may be a compound statement.
43: If an exception is raised using the
44: .IR raise ()
45: function during
46: .I statement1
47: (or during any functions called by
48: .IR statement1 ),
49: the stack will be unwound and
50: .I statement2
51: will be invoked in the current context. However, if the exception
52: handler is redeclared in a
53: .I dynamically
54: enclosed statement, the current exception handler will be inactive during
55: the execution of the enclosed statement.
56: .PP
57: During the execution of
58: .IR statement2 ,
59: two predefined values may be used:
60: .IR Exception.Code ,
61: an integer, is the value of
62: .I code
63: passed to the
64: .IR raise ()
65: call which invoked the handler, and
66: .IR Exception.Message
67: is the value of
68: .IR msg .
69: It is up to the user to define the values used for the exception
70: codes; by convention, small positive integers are interpreted
71: as Unix error codes.
72: .PP
73: As an example of the use of this package, the following ``toy'' code
74: computes the quotient of variables f1 and f2, unless f2 is 0.0:
75: .sp
76: .nf
77: DURING {
78: if (f2 == 0.0)
79: raise(DIVIDE_BY_ZERO, "Division by zero attempted");
80: quotient = f1/ f2;
81: } HANDLER
82: switch (Exception.Code) {
83: case DIVIDE_BY_ZERO:
84: return(HUGE);
85: break;
86: default:
87: printf("Unexpected error %s\\n", Exception.Message);
88: }
89: END_HANDLER
90: .fi
91: .PP
92: If a handler does not want to take responsibility for an exception,
93: it can ``pass the buck'' to the dynamically enclosing exception
94: handler by use of the
95: .I RERAISE
96: macro, which simply raises the exception that invoked the handler.
97: Of course, it is possible that there is no higher-level handler.
98: The programmer can control the action in this case by setting the
99: external int
100: .I ExceptMode
101: to some (bit-wise OR'd) combination of the following constants:
102: .IP "EX_MODE_REPORT" 1.5i
103: Print a message on stderr if an exception is not caught. If this
104: is not set, no message is printed.
105: .IP "EX_MODE_ABORT" 1.5i
106: Calls the
107: .IR abort (3)
108: routine if an exception is not caught. If this is not set,
109: .IR exit (3)
110: is called, with the exception code as an argument.
111: .PP
112: The default value for
113: .I ExceptMode
114: is zero.
115: .SH RESTRICTIONS
116: .B THESE RESTRICTIONS ARE IMPORTANT;
117: YOU WILL SUFFER IF YOU DISOBEY THEM.
118: .PP
119: During the execution of
120: .IR statement1,
121: no transfers out of the statement are allowed, except as noted here.
122: Execution of a compound
123: .I statement1
124: must ``run off the end'' of the block. This means that
125: .I statement1
126: may not include a
127: .B return
128: or
129: .BR goto ,
130: or a
131: .B break
132: or
133: .B continue
134: that would affect a loop enclosing the
135: .I DURING ... END_HANDLER
136: block. The
137: .I statement1
138: may include a call to
139: .IR raise ()
140: (but not
141: .IR RERAISE ),
142: .IR exit (3),
143: and any statement at all may be used in a function called.
144: .PP
145: If you wish to use a
146: .B return
147: within
148: .IR statement1 ,
149: you must instead use
150: .I E_RETURN()
151: to return a value,
152: or
153: .I E_RETURN_VOID
154: if the enclosing function is declared
155: .BR void .
156: These two macros may be used
157: .I only
158: in the (lexically) outermost
159: .I statement1
160: of a function, and nowhere else.
161: .PP
162: There are no restrictions on what may be done inside the
163: .I statement2
164: part of a handler block, except that it is subject to the
165: above constraints if it is lexically enclosed in the
166: .I statement1
167: part of another handler.
168: .PP
169: As an aid to Unix programmers, the
170: .IR raise_sys ()
171: function is provided. It is used exactly as
172: .IR raise ()
173: is, except that it uses the global
174: .IR errno (3)
175: to produce the exception code and message.
176: .SH SEE ALSO
177: errno(3), setjmp(3)
178: .SH AUTHOR
179: Jeffrey Mogul (Stanford)
180: .SH BUGS
181: Due to a limitation of the
182: .IR setjmp (3)
183: implementation,
184: .B register
185: variables which are actually stored in registers (and this is not
186: always easy to determine, and especially is not portable) are restored
187: to the values they had upon entering
188: .I statement1
189: when the handler
190: .RI ( statement2 )
191: is invoked. All other data keeps whatever values they were assigned
192: during the (interrupted) execution of
193: .IR statement1 .
194: A good rule to follow is that you should not rely on the values of
195: variables declared
196: .B register
197: (in the current block) after an exception has been caught.
198:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.