00001 /* 00002 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 00003 * 00004 * @APPLE_LICENSE_HEADER_START@ 00005 * 00006 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 00007 * Reserved. This file contains Original Code and/or Modifications of 00008 * Original Code as defined in and that are subject to the Apple Public 00009 * Source License Version 1.1 (the "License"). You may not use this file 00010 * except in compliance with the License. Please obtain a copy of the 00011 * License at http://www.apple.com/publicsource and read it before using 00012 * this file. 00013 * 00014 * The Original Code and all software distributed under the License are 00015 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 00016 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 00017 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 00018 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the 00019 * License for the specific language governing rights and limitations 00020 * under the License. 00021 * 00022 * @APPLE_LICENSE_HEADER_END@ 00023 */ 00024 00025 /* 00026 error.h 00027 00028 This file defines the interface to the exception raising scheme. 00029 00030 Copyright (c) 1988-1996 NeXT Software, Inc. as an unpublished work. 00031 All rights reserved. 00032 */ 00033 00034 #warning The API in this header is obsoleted by NSException et al. 00035 00036 #ifndef _OBJC_ERROR_H_ 00037 #define _OBJC_ERROR_H_ 00038 00039 #include <setjmp.h> 00040 #import <objc/objc-api.h> 00041 00042 00043 typedef struct _NXHandler { /* a node in the handler chain */ 00044 jmp_buf jumpState; /* place to longjmp to */ 00045 struct _NXHandler *next; /* ptr to next handler */ 00046 int code; /* error code of exception */ 00047 const void *data1, *data2; /* blind data for describing error */ 00048 } NXHandler; 00049 00050 00051 /* Handles RAISE's with nowhere to longjmp to */ 00052 typedef void NXUncaughtExceptionHandler(int code, const void *data1, 00053 const void *data2); 00054 OBJC_EXPORT NXUncaughtExceptionHandler *_NXUncaughtExceptionHandler; 00055 #define NXGetUncaughtExceptionHandler() _NXUncaughtExceptionHandler 00056 #define NXSetUncaughtExceptionHandler(proc) \ 00057 (_NXUncaughtExceptionHandler = (proc)) 00058 00059 /* NX_DURING, NX_HANDLER and NX_ENDHANDLER are always used like: 00060 00061 NX_DURING 00062 some code which might raise an error 00063 NX_HANDLER 00064 code that will be jumped to if an error occurs 00065 NX_ENDHANDLER 00066 00067 If any error is raised within the first block of code, the second block 00068 of code will be jumped to. Typically, this code will clean up any 00069 resources allocated in the routine, possibly case on the error code 00070 and perform special processing, and default to RERAISE the error to 00071 the next handler. Within the scope of the handler, a local variable 00072 called NXLocalHandler of type NXHandler holds information about the 00073 error raised. 00074 00075 It is illegal to exit the first block of code by any other means than 00076 NX_VALRETURN, NX_VOIDRETURN, or just falling out the bottom. 00077 */ 00078 00079 /* private support routines. Do not call directly. */ 00080 OBJC_EXPORT void _NXAddHandler( NXHandler *handler ); 00081 OBJC_EXPORT void _NXRemoveHandler( NXHandler *handler ); 00082 00083 #define NX_DURING { NXHandler NXLocalHandler; \ 00084 _NXAddHandler(&NXLocalHandler); \ 00085 if( !_setjmp(NXLocalHandler.jumpState) ) { 00086 00087 #define NX_HANDLER _NXRemoveHandler(&NXLocalHandler); } else { 00088 00089 #define NX_ENDHANDLER }} 00090 00091 #define NX_VALRETURN(val) do { typeof(val) temp = (val); \ 00092 _NXRemoveHandler(&NXLocalHandler); \ 00093 return(temp); } while (0) 00094 00095 #define NX_VOIDRETURN do { _NXRemoveHandler(&NXLocalHandler); \ 00096 return; } while (0) 00097 00098 /* RAISE and RERAISE are called to indicate an error condition. They 00099 initiate the process of jumping up the chain of handlers. 00100 */ 00101 00102 OBJC_EXPORT 00103 #if defined(__GNUC__) && !defined(__STRICT_ANSI__) 00104 volatile /* never returns */ 00105 #endif 00106 void _NXRaiseError(int code, const void *data1, const void *data2) 00107 #if defined(__GNUC__) 00108 __attribute__ ((noreturn)) 00109 #endif 00110 ; 00111 00112 #define NX_RAISE( code, data1, data2 ) \ 00113 _NXRaiseError( (code), (data1), (data2) ) 00114 00115 #define NX_RERAISE() _NXRaiseError( NXLocalHandler.code, \ 00116 NXLocalHandler.data1, NXLocalHandler.data2 ) 00117 00118 /* These routines set and return the procedure which is called when 00119 exceptions are raised. This procedure must NEVER return. It will 00120 usually either longjmp, or call the uncaught exception handler. 00121 The default exception raiser is also declared 00122 */ 00123 typedef volatile void NXExceptionRaiser(int code, const void *data1, const void *data2); 00124 OBJC_EXPORT void NXSetExceptionRaiser(NXExceptionRaiser *proc); 00125 OBJC_EXPORT NXExceptionRaiser *NXGetExceptionRaiser(void); 00126 OBJC_EXPORT NXExceptionRaiser NXDefaultExceptionRaiser; 00127 00128 00129 /* The error buffer is used to allocate data which is passed up to other 00130 handlers. Clients should clear the error buffer in their top level 00131 handler. The Application Kit does this. 00132 */ 00133 OBJC_EXPORT void NXAllocErrorData(int size, void **data); 00134 OBJC_EXPORT void NXResetErrorData(void); 00135 00136 #endif /* _OBJC_ERROR_H_ */