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 >
C/C++ Source or Header  |  1990-07-10  |  5KB  |  198 lines

  1. /*
  2.  * Copyright (c) 1987, 1989 University of Maryland
  3.  * Department of Computer Science.  All rights reserved.
  4.  * Permission to copy for any purpose is hereby granted
  5.  * so long as this copyright notice remains intact.
  6.  */
  7.  
  8. #ifndef lint
  9. 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 $";
  10. #endif
  11.  
  12. /*
  13.  * Print an error message with an optional system error number, and
  14.  * optionally quit.
  15.  *
  16.  * THIS CODE IS SYSTEM DEPENDENT UNLESS varargs WORKS WITH vprintf
  17.  * OR _doprnt.  It should work properly under System V using vprintf.
  18.  * (If you have vprintf, define HAVE_VPRINTF in ../h/types.h.)
  19.  */
  20.  
  21. #include "types.h"        /* for HAVE_VPRINTF */
  22. #include "error.h"
  23. #include <stdio.h>
  24. #include <varargs.h>
  25.  
  26. #if defined(lint) && !defined(LINT_ANYWAY)
  27.  
  28. /* ARGSUSED */
  29. void SetErrorTrap(fn) void (*fn)(); {;}
  30.  
  31. /* VARARGS3 ARGSUSED */
  32. void error(quit, e, fmt) int quit, e; char *fmt; {;}
  33.  
  34. /* VARARGS1 ARGSUSED */
  35. void panic(fmt) char *fmt; { exit(1); /* NOTREACHED */ }
  36.  
  37. #else lint
  38.  
  39. extern char *ProgName;        /* program name from argv[0] */
  40. extern int errno;        /* Unix system-call error */
  41. extern char *sys_errlist[];    /* table of error number => string */
  42. extern int sys_nerr;        /* size of table */
  43.  
  44. static FILE *trap_file;        /* error diversion file, if any */
  45. static void (*trap_fn)();    /* trap function */
  46. static char *trap_buf;        /* buffer for trapped error strings */
  47. static int trap_size;        /* size of trap_buf */
  48.  
  49. extern char *malloc(), *realloc();
  50.  
  51. /*
  52.  * Enable error trapping: register the function fn as the trapper.
  53.  * If fn is NULL, stop trapping.
  54.  */
  55. void
  56. SetErrorTrap(fn)
  57.     void (*fn)();
  58. {
  59.     int tempfd;
  60.     char fname[BUFSIZ];
  61.  
  62.     /* shut down any existing error trap */
  63.     if (trap_file) {
  64.         (void) fclose(trap_file);
  65.         trap_file = NULL;
  66.     }
  67.     if ((trap_fn = fn) == NULL)
  68.         return;
  69.     /* begin trapping */
  70.     if ((tempfd = MakeRWTempFile(fname)) < 0)
  71.         error(1, -1, "cannot create temporary file %s", fname);
  72.     if (trap_size == 0) {
  73.         trap_buf = malloc((unsigned)(trap_size = 1000));
  74.         if (trap_buf == 0)
  75.             error(1, -1,
  76.                 "cannot get space for error buffer");
  77.     }
  78.     if ((trap_file = fdopen(tempfd, "r+")) == NULL)
  79.         error(1, -1, "cannot get stdio file for error trap");
  80. }
  81.  
  82. /*
  83.  * Read a trapped error into trap_buf.
  84.  * Return a pointer to the (NUL-terminated) text.
  85.  * If something goes wrong, return something else printable.
  86.  */
  87. static char *
  88. readback()
  89. {
  90.     int nbytes = ftell(trap_file) + 1;
  91.  
  92.     if (nbytes > trap_size) {
  93.         if (trap_buf == NULL)
  94.             trap_buf = malloc((unsigned)nbytes);
  95.         else
  96.             trap_buf = realloc(trap_buf, (unsigned)nbytes);
  97.         if (trap_buf == NULL) {
  98.             trap_size = 0;
  99.             return ("Ouch!  Lost error text: out of memory?");
  100.         }
  101.     }
  102.     rewind(trap_file);    /* now can read */
  103.     nbytes = fread(trap_buf, 1, nbytes, trap_file);
  104.     if (nbytes < 0)
  105.         return ("Ouch!  Trouble reading error text!");
  106.     trap_buf[nbytes] = 0;
  107.     return (trap_buf);
  108. }
  109.  
  110. /*
  111.  * Print an error message to the error output (either stderr, or
  112.  * if trapping errors, to the error trap file).  We precede this
  113.  * with the program's name and an optional string (a0), then use
  114.  * the format and variable argument list, then append an optional
  115.  * Unix error string.  Finally, if errors are being trapped, we
  116.  * pass the error text and the quit flag to the trap function.
  117.  *
  118.  * In the interest of `look and feel', if errors are being trapped,
  119.  * the program name is omitted.
  120.  */
  121. static void
  122. verror(quit, a0, fmt, l, e)
  123.     char *a0, *fmt;
  124.     va_list l;
  125.     int e;
  126. {
  127.     register FILE *fp = trap_file;
  128.  
  129.     /* print to the trap file, if any, else stderr */
  130.     if ((fp = trap_file) != NULL)
  131.         rewind(fp);        /* now can write */
  132.     else {
  133.         fp = stderr;
  134.         (void) fflush(fp);
  135.     }
  136.     if (trap_file == NULL)
  137.         (void) fprintf(fp, "%s: ", ProgName);
  138.     if (a0)
  139.         (void) fprintf(fp, "%s", a0);
  140. #ifdef HAVE_VPRINTF
  141.     (void) vfprintf(fp, fmt, l);
  142. #else
  143.     (void) _doprnt(fmt, l, fp);
  144. #endif
  145.     if (e) {
  146.         if (e < sys_nerr)
  147.             (void) fprintf(fp, ": %s", sys_errlist[e]);
  148.         else
  149.             (void) fprintf(fp, ": Unknown error code %d", e);
  150.     }
  151.     (void) putc('\n', fp);
  152.     (void) fflush(fp);
  153.     if (trap_file != NULL)
  154.         (*trap_fn)(quit, readback());
  155.     if (quit)
  156.         exit(quit);
  157. }
  158.  
  159. /*
  160.  * Print an error message and optionally quit.
  161.  */
  162. void
  163. error(va_alist)
  164.     va_dcl
  165. {
  166.     va_list l;
  167.     int quit, e;
  168.     char *fmt;
  169.  
  170.     va_start(l);
  171.     quit = va_arg(l, int);
  172.     if ((e = va_arg(l, int)) < 0)
  173.         e = errno;
  174.     fmt = va_arg(l, char *);
  175.     verror(quit, (char *)NULL, fmt, l, e);
  176.     va_end(l);
  177. }
  178.  
  179. /*
  180.  * Panic (print to stderr and abort).
  181.  */
  182. void
  183. panic(va_alist)
  184.     va_dcl
  185. {
  186.     va_list l;
  187.     char *fmt;
  188.  
  189.     SetErrorTrap((void (*)())NULL);    /* shut down any trap */
  190.     va_start(l);
  191.     fmt = va_arg(l, char *);
  192.     verror(0, "panic: ", fmt, l, 0);
  193.     va_end(l);
  194.     abort();
  195. }
  196.  
  197. #endif /* lint */
  198.