1 /******************************************************************************
2 ** Filename: danerror.c
3 ** Purpose: Routines for managing error trapping
4 ** Author: Dan Johnson
5 ** History: 3/17/89, DSJ, Created.
6 **
7 ** (c) Copyright Hewlett-Packard Company, 1988.
8 ** Licensed under the Apache License, Version 2.0 (the "License");
9 ** you may not use this file except in compliance with the License.
10 ** You may obtain a copy of the License at
11 ** http://www.apache.org/licenses/LICENSE-2.0
12 ** Unless required by applicable law or agreed to in writing, software
13 ** distributed under the License is distributed on an "AS IS" BASIS,
14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ** See the License for the specific language governing permissions and
16 ** limitations under the License.
17 ******************************************************************************/
18 /**----------------------------------------------------------------------------
19 Include Files and Type Defines
20 ----------------------------------------------------------------------------**/
21 #include "general.h"
22 #include "danerror.h"
23 #include "callcpp.h"
24 #include "globaloc.h"
25 #ifdef __UNIX__
26 #include "assert.h"
27 #endif
28
29 #include <stdio.h>
30 #include <setjmp.h>
31
32 #define MAXTRAPDEPTH 100
33
34 #define ERRORTRAPDEPTH 1000
35
36 /**----------------------------------------------------------------------------
37 Global Data Definitions and Declarations
38 ----------------------------------------------------------------------------**/
39 static jmp_buf ErrorTrapStack[MAXTRAPDEPTH];
40 static VOID_PROC ProcTrapStack[MAXTRAPDEPTH];
41 static inT32 CurrentTrapDepth = 0;
42
43 /**----------------------------------------------------------------------------
44 Public Code
45 ----------------------------------------------------------------------------**/
46 /*---------------------------------------------------------------------------*/
ReleaseErrorTrap()47 void ReleaseErrorTrap() {
48 /*
49 ** Parameters:
50 ** None
51 ** Globals:
52 ** CurrentTrapDepth number of traps on the stack
53 ** Operation:
54 ** This routine removes the current error trap from the
55 ** error trap stack, thus returning control to the previous
56 ** error trap. If the error trap stack is empty, nothing is
57 ** done.
58 ** Return:
59 ** None
60 ** Exceptions:
61 ** None
62 ** History:
63 ** 4/3/89, DSJ, Created.
64 */
65 if (CurrentTrapDepth > 0) {
66 CurrentTrapDepth--;
67 }
68 } /* ReleaseErrorTrap */
69
70
71 /*---------------------------------------------------------------------------*/
DoError(int Error,const char * Message)72 void DoError(int Error, const char *Message) {
73 /*
74 ** Parameters:
75 ** Error error number which is to be trapped
76 ** Message pointer to a string to be printed as an error message
77 ** Globals:
78 ** ErrorTrapStack stack of error traps
79 ** CurrentTrapDepth number of traps on the stack
80 ** Operation:
81 ** This routine prints the specified error message to stderr.
82 ** It then jumps to the current error trap. If the error trap
83 ** stack is empty, the calling program is terminated with a
84 ** fatal error message.
85 ** Return:
86 ** None - this routine does not return.
87 ** Exceptions:
88 ** Empty error trap stack terminates the calling program.
89 ** History:
90 ** 4/3/89, DSJ, Created.
91 */
92 if (Message != NULL) {
93 cprintf ("\nError: %s!\n", Message);
94 }
95
96 if (CurrentTrapDepth <= 0) {
97 cprintf ("\nFatal error: No error trap defined!\n");
98
99 /* SPC 20/4/94
100 There used to be a call to abort() here. I've changed it to call into the
101 C++ error code to generate a meaningful status code
102 */
103 signal_termination_handler(Error);
104 }
105
106 if (ProcTrapStack[CurrentTrapDepth - 1] != DO_NOTHING)
107 (*ProcTrapStack[CurrentTrapDepth - 1]) ();
108
109 longjmp (ErrorTrapStack[CurrentTrapDepth - 1], 1);
110 } /* DoError */
111
112
113 /**----------------------------------------------------------------------------
114 Private Code
115 ----------------------------------------------------------------------------**/
116 /*---------------------------------------------------------------------------*/
PushErrorTrap(VOID_PROC Procedure)117 jmp_buf &PushErrorTrap(VOID_PROC Procedure) {
118 /*
119 ** Parameters:
120 ** Procedure trap procedure to execute
121 ** Globals:
122 ** ErrorTrapStack stack of error traps
123 ** CurrentTrapDepth number of traps on the stack
124 ** Operation:
125 ** This routine pushes a new error trap onto the top of
126 ** the error trap stack. This new error trap can then be
127 ** used in a call to setjmp. This trap is then in effect
128 ** until ReleaseErrorTrap is called. WARNING: a procedure
129 ** that calls PushErrorTrap should never exit before calling
130 ** ReleaseErrorTrap.
131 ** Return:
132 ** Pointer to a new error trap buffer
133 ** Exceptions:
134 ** Traps an error if the error trap stack is already full
135 ** History:
136 ** 3/17/89, DSJ, Created.
137 ** 9/12/90, DSJ, Added trap procedure parameter.
138 */
139 if (CurrentTrapDepth >= MAXTRAPDEPTH)
140 DoError (ERRORTRAPDEPTH, "Error trap depth exceeded");
141 ProcTrapStack[CurrentTrapDepth] = Procedure;
142 return ErrorTrapStack[CurrentTrapDepth++];
143
144 } /* PushErrorTrap */
145