|
|
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.