home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
s
/
stex2-18.zip
/
SeeTeX
/
libtex
/
error.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-10
|
5KB
|
198 lines
/*
* Copyright (c) 1987, 1989 University of Maryland
* Department of Computer Science. All rights reserved.
* Permission to copy for any purpose is hereby granted
* so long as this copyright notice remains intact.
*/
#ifndef lint
static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/lib/RCS/error.c,v 2.8 89/08/22 21:49:12 chris Exp $";
#endif
/*
* Print an error message with an optional system error number, and
* optionally quit.
*
* THIS CODE IS SYSTEM DEPENDENT UNLESS varargs WORKS WITH vprintf
* OR _doprnt. It should work properly under System V using vprintf.
* (If you have vprintf, define HAVE_VPRINTF in ../h/types.h.)
*/
#include "types.h" /* for HAVE_VPRINTF */
#include "error.h"
#include <stdio.h>
#include <varargs.h>
#if defined(lint) && !defined(LINT_ANYWAY)
/* ARGSUSED */
void SetErrorTrap(fn) void (*fn)(); {;}
/* VARARGS3 ARGSUSED */
void error(quit, e, fmt) int quit, e; char *fmt; {;}
/* VARARGS1 ARGSUSED */
void panic(fmt) char *fmt; { exit(1); /* NOTREACHED */ }
#else lint
extern char *ProgName; /* program name from argv[0] */
extern int errno; /* Unix system-call error */
extern char *sys_errlist[]; /* table of error number => string */
extern int sys_nerr; /* size of table */
static FILE *trap_file; /* error diversion file, if any */
static void (*trap_fn)(); /* trap function */
static char *trap_buf; /* buffer for trapped error strings */
static int trap_size; /* size of trap_buf */
extern char *malloc(), *realloc();
/*
* Enable error trapping: register the function fn as the trapper.
* If fn is NULL, stop trapping.
*/
void
SetErrorTrap(fn)
void (*fn)();
{
int tempfd;
char fname[BUFSIZ];
/* shut down any existing error trap */
if (trap_file) {
(void) fclose(trap_file);
trap_file = NULL;
}
if ((trap_fn = fn) == NULL)
return;
/* begin trapping */
if ((tempfd = MakeRWTempFile(fname)) < 0)
error(1, -1, "cannot create temporary file %s", fname);
if (trap_size == 0) {
trap_buf = malloc((unsigned)(trap_size = 1000));
if (trap_buf == 0)
error(1, -1,
"cannot get space for error buffer");
}
if ((trap_file = fdopen(tempfd, "r+")) == NULL)
error(1, -1, "cannot get stdio file for error trap");
}
/*
* Read a trapped error into trap_buf.
* Return a pointer to the (NUL-terminated) text.
* If something goes wrong, return something else printable.
*/
static char *
readback()
{
int nbytes = ftell(trap_file) + 1;
if (nbytes > trap_size) {
if (trap_buf == NULL)
trap_buf = malloc((unsigned)nbytes);
else
trap_buf = realloc(trap_buf, (unsigned)nbytes);
if (trap_buf == NULL) {
trap_size = 0;
return ("Ouch! Lost error text: out of memory?");
}
}
rewind(trap_file); /* now can read */
nbytes = fread(trap_buf, 1, nbytes, trap_file);
if (nbytes < 0)
return ("Ouch! Trouble reading error text!");
trap_buf[nbytes] = 0;
return (trap_buf);
}
/*
* Print an error message to the error output (either stderr, or
* if trapping errors, to the error trap file). We precede this
* with the program's name and an optional string (a0), then use
* the format and variable argument list, then append an optional
* Unix error string. Finally, if errors are being trapped, we
* pass the error text and the quit flag to the trap function.
*
* In the interest of `look and feel', if errors are being trapped,
* the program name is omitted.
*/
static void
verror(quit, a0, fmt, l, e)
char *a0, *fmt;
va_list l;
int e;
{
register FILE *fp = trap_file;
/* print to the trap file, if any, else stderr */
if ((fp = trap_file) != NULL)
rewind(fp); /* now can write */
else {
fp = stderr;
(void) fflush(fp);
}
if (trap_file == NULL)
(void) fprintf(fp, "%s: ", ProgName);
if (a0)
(void) fprintf(fp, "%s", a0);
#ifdef HAVE_VPRINTF
(void) vfprintf(fp, fmt, l);
#else
(void) _doprnt(fmt, l, fp);
#endif
if (e) {
if (e < sys_nerr)
(void) fprintf(fp, ": %s", sys_errlist[e]);
else
(void) fprintf(fp, ": Unknown error code %d", e);
}
(void) putc('\n', fp);
(void) fflush(fp);
if (trap_file != NULL)
(*trap_fn)(quit, readback());
if (quit)
exit(quit);
}
/*
* Print an error message and optionally quit.
*/
void
error(va_alist)
va_dcl
{
va_list l;
int quit, e;
char *fmt;
va_start(l);
quit = va_arg(l, int);
if ((e = va_arg(l, int)) < 0)
e = errno;
fmt = va_arg(l, char *);
verror(quit, (char *)NULL, fmt, l, e);
va_end(l);
}
/*
* Panic (print to stderr and abort).
*/
void
panic(va_alist)
va_dcl
{
va_list l;
char *fmt;
SetErrorTrap((void (*)())NULL); /* shut down any trap */
va_start(l);
fmt = va_arg(l, char *);
verror(0, "panic: ", fmt, l, 0);
va_end(l);
abort();
}
#endif /* lint */