• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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