/*static char *SCCSID = "@(#)error.c	6.1 90/11/18";*/
/*static char *SCCSID = "@(#)error.c 13.4 90/09/07";*/
/***	ERROR.C - Routines to deal with error conditions.
 *
 *	Format
 *	Michael Walma
 *	Copyright March 1988, Microsoft Corp.
 *	March 28 1988
 *
 *	Modification History:
 *	M. Walma	03/28/88.	Original for Pinball 1.0.
 */

#include <setjmp.h>
#include "ldefs.h"
#include "ltypes.h"
#include "globals.h"
#include <pr_fmt.h>

extern jmp_buf fmt_error;

/***	exit_error - print error message, end program
 *
 *	exit_error accepts an error code, prints an appropriate
 *	message, cleans up any allocated  resources, and ends
 *	execution of the program.  Note that this routine never returns.
 *
 *	Since the OS/2 front end programs expect the IFS's dynamic link
 *	routine to return with an errorlevel value (rather than just
 *	terminating the program themselves), fmt_exit_error uses the
 *	C library's "longjmp" routine to jump back to an error-handling
 *	clause in the top-level routine.
 *
 *	exit_error	(code)
 *
 *	ENTRY		code - error code, defined in DEFS.H
 *
 *	EXIT		Does not return
 *
 *	CALLS		allow_signals
 *			close_disk
 *			computmsg
 *			longjmp
 *
 *	WARNINGS	Terminates program
 *
 *	EFFECTS 	Returns to error clause in format()
 *			Frees all dynamic memory
 *			Closes disk
 */
void fmt_exit_error (code)
  USHORT code;
{
#ifdef TRACE
  fprintf (stderr, "fmt_exit_error (%d)\n", code);
  fflush (stderr);
#endif

/*
 * Print the message associated with the error code.
 */

  if ((code <= MAX_ERROR_CODE) && (fmt_error_message [code]))
    FMT_COMPUTMSG( SYSTEM_MSG, NULL, 0, fmt_error_message [code], msgfilename, STDERR_CODE,
	       NO_RESPONSE, NULL, 0);
  else if (code > MAX_ERROR_CODE) {
    itoa (code, scratchptr, 10);
    FMT_COMPUTMSG( SYSTEM_MSG, &scratchptr, 1, FMT_UNKNOWN_ERROR_STR, msgfilename, STDERR_CODE,
	       NO_RESPONSE, NULL, 0);
  }

/*
 * Unlock and close the disk handle.
 */

  close_disk ();

/*
 * Free up allocated memory.
 */

  FREE_HUGE (bitmap);
  FREE_BLOCK (fmt_bad);
#ifdef TWO_MAPS
  FREE_BLOCK (fmt_bad2);
#endif

  FREE_BLOCK (fmt_free_ind [0]);
#ifdef TWO_MAPS
  FREE_BLOCK (fmt_free_ind [1]);
#endif

  allow_signals ();

/*
 * Jump back to format().
 */

  longjmp (fmt_error, 0);
}
