blob: 0730b37289f8680c0f1feb0914c01d8e3fbe5889 [file] [log] [blame]
/******************************************************************************
** Filename: danerror.c
** Purpose: Routines for managing error trapping
** Author: Dan Johnson
** History: 3/17/89, DSJ, Created.
**
** (c) Copyright Hewlett-Packard Company, 1988.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
******************************************************************************/
/**----------------------------------------------------------------------------
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "general.h"
#include "danerror.h"
#include "callcpp.h"
#include "globaloc.h"
#ifdef __UNIX__
#include "assert.h"
#endif
#include <stdio.h>
#include <setjmp.h>
#define MAXTRAPDEPTH 100
#define ERRORTRAPDEPTH 1000
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/
static jmp_buf ErrorTrapStack[MAXTRAPDEPTH];
static VOID_PROC ProcTrapStack[MAXTRAPDEPTH];
static inT32 CurrentTrapDepth = 0;
/**----------------------------------------------------------------------------
Public Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
void ReleaseErrorTrap() {
/*
** Parameters:
** None
** Globals:
** CurrentTrapDepth number of traps on the stack
** Operation:
** This routine removes the current error trap from the
** error trap stack, thus returning control to the previous
** error trap. If the error trap stack is empty, nothing is
** done.
** Return:
** None
** Exceptions:
** None
** History:
** 4/3/89, DSJ, Created.
*/
if (CurrentTrapDepth > 0) {
CurrentTrapDepth--;
}
} /* ReleaseErrorTrap */
/*---------------------------------------------------------------------------*/
void DoError(int Error, const char *Message) {
/*
** Parameters:
** Error error number which is to be trapped
** Message pointer to a string to be printed as an error message
** Globals:
** ErrorTrapStack stack of error traps
** CurrentTrapDepth number of traps on the stack
** Operation:
** This routine prints the specified error message to stderr.
** It then jumps to the current error trap. If the error trap
** stack is empty, the calling program is terminated with a
** fatal error message.
** Return:
** None - this routine does not return.
** Exceptions:
** Empty error trap stack terminates the calling program.
** History:
** 4/3/89, DSJ, Created.
*/
if (Message != NULL) {
cprintf ("\nError: %s!\n", Message);
}
if (CurrentTrapDepth <= 0) {
cprintf ("\nFatal error: No error trap defined!\n");
/* SPC 20/4/94
There used to be a call to abort() here. I've changed it to call into the
C++ error code to generate a meaningful status code
*/
signal_termination_handler(Error);
}
if (ProcTrapStack[CurrentTrapDepth - 1] != DO_NOTHING)
(*ProcTrapStack[CurrentTrapDepth - 1]) ();
longjmp (ErrorTrapStack[CurrentTrapDepth - 1], 1);
} /* DoError */
/**----------------------------------------------------------------------------
Private Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
jmp_buf &PushErrorTrap(VOID_PROC Procedure) {
/*
** Parameters:
** Procedure trap procedure to execute
** Globals:
** ErrorTrapStack stack of error traps
** CurrentTrapDepth number of traps on the stack
** Operation:
** This routine pushes a new error trap onto the top of
** the error trap stack. This new error trap can then be
** used in a call to setjmp. This trap is then in effect
** until ReleaseErrorTrap is called. WARNING: a procedure
** that calls PushErrorTrap should never exit before calling
** ReleaseErrorTrap.
** Return:
** Pointer to a new error trap buffer
** Exceptions:
** Traps an error if the error trap stack is already full
** History:
** 3/17/89, DSJ, Created.
** 9/12/90, DSJ, Added trap procedure parameter.
*/
if (CurrentTrapDepth >= MAXTRAPDEPTH)
DoError (ERRORTRAPDEPTH, "Error trap depth exceeded");
ProcTrapStack[CurrentTrapDepth] = Procedure;
return ErrorTrapStack[CurrentTrapDepth++];
} /* PushErrorTrap */