|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.0 (the 'License'). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License."
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: error.h
27:
28: This file defines the interface to the exception raising scheme.
29:
30: Copyright (c) 1988 NeXT, Inc. as an unpublished work.
31: All rights reserved.
32: */
33:
34: #ifndef _OBJC_ERROR_H_
35: #define _OBJC_ERROR_H_
36:
37: #include <setjmp.h>
38:
39: typedef struct _NXHandler { /* a node in the handler chain */
40: jmp_buf jumpState; /* place to longjmp to */
41: struct _NXHandler *next; /* ptr to next handler */
42: int code; /* error code of exception */
43: const void *data1, *data2; /* blind data for describing error */
44: } NXHandler;
45:
46:
47: /* Handles RAISE's with nowhere to longjmp to */
48: typedef void NXUncaughtExceptionHandler(int code, const void *data1,
49: const void *data2);
50: extern NXUncaughtExceptionHandler *_NXUncaughtExceptionHandler;
51: #define NXGetUncaughtExceptionHandler() _NXUncaughtExceptionHandler
52: #define NXSetUncaughtExceptionHandler(proc) \
53: (_NXUncaughtExceptionHandler = (proc))
54:
55: /* NX_DURING, NX_HANDLER and NX_ENDHANDLER are always used like:
56:
57: NX_DURING
58: some code which might raise an error
59: NX_HANDLER
60: code that will be jumped to if an error occurs
61: NX_ENDHANDLER
62:
63: If any error is raised within the first block of code, the second block
64: of code will be jumped to. Typically, this code will clean up any
65: resources allocated in the routine, possibly case on the error code
66: and perform special processing, and default to RERAISE the error to
67: the next handler. Within the scope of the handler, a local variable
68: called NXLocalHandler of type NXHandler holds information about the
69: error raised.
70:
71: It is illegal to exit the first block of code by any other means than
72: NX_VALRETURN, NX_VOIDRETURN, or just falling out the bottom.
73: */
74:
75: /* private support routines. Do not call directly. */
76: extern void _NXAddHandler( NXHandler *handler );
77: extern void _NXRemoveHandler( NXHandler *handler );
78: extern _setjmp(jmp_buf env);
79:
80: #define NX_DURING { NXHandler NXLocalHandler; \
81: _NXAddHandler(&NXLocalHandler); \
82: if( !_setjmp(NXLocalHandler.jumpState) ) {
83:
84: #define NX_HANDLER _NXRemoveHandler(&NXLocalHandler); } else {
85:
86: #define NX_ENDHANDLER }}
87:
88: #define NX_VALRETURN(val) do { typeof(val) temp = (val); \
89: _NXRemoveHandler(&NXLocalHandler); \
90: return(temp); } while (0)
91:
92: #define NX_VOIDRETURN do { _NXRemoveHandler(&NXLocalHandler); \
93: return; } while (0)
94:
95: /* RAISE and RERAISE are called to indicate an error condition. They
96: initiate the process of jumping up the chain of handlers.
97: */
98:
99: extern
100: #ifdef __GNUC__
101: #ifndef __STRICT_ANSI__
102: __volatile /* never returns */
103: #endif /* not __STRICT_ANSI__ */
104: #endif /* __GNUC__ */
105: void _NXRaiseError(int code, const void *data1, const void *data2)
106: #ifdef __GNUC__
107: __attribute__ ((noreturn))
108: #endif
109: ;
110:
111: #define NX_RAISE( code, data1, data2 ) \
112: _NXRaiseError( (code), (data1), (data2) )
113:
114: #define NX_RERAISE() _NXRaiseError( NXLocalHandler.code, \
115: NXLocalHandler.data1, NXLocalHandler.data2 )
116:
117: /* These routines set and return the procedure which is called when
118: exceptions are raised. This procedure must NEVER return. It will
119: usually either longjmp, or call the uncaught exception handler.
120: The default exception raiser is also declared
121: */
122: typedef volatile void NXExceptionRaiser(int code, const void *data1, const void *data2);
123: extern void NXSetExceptionRaiser(NXExceptionRaiser *proc);
124: extern NXExceptionRaiser *NXGetExceptionRaiser(void);
125: extern NXExceptionRaiser NXDefaultExceptionRaiser;
126:
127:
128: /* The error buffer is used to allocate data which is passed up to other
129: handlers. Clients should clear the error buffer in their top level
130: handler. The Application Kit does this.
131: */
132: extern void NXAllocErrorData(int size, void **data);
133: extern void NXResetErrorData(void);
134:
135: #endif /* _OBJC_ERROR_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.