123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* $Header$ */
- /* E R R O R A N D D I A G N O S T I C R O U T I N E S */
- #include <varargs.h>
- #include <system.h>
- #include <em.h>
- #include "lint.h"
- #include "nopp.h"
- #include "errout.h"
- #include "debug.h"
- #include "tokenname.h"
- #include "arith.h"
- #include "label.h"
- #include "expr.h"
- #include "def.h"
- #include "LLlex.h"
- /* This file contains the error-message and diagnostic
- functions. Beware, they are called with a variable number of
- arguments!
- */
- /* error classes */
- #define WARNING 1
- #define ERROR 2
- #define CRASH 3
- #define FATAL 4
- int err_occurred = 0;
- extern char options[];
- #ifdef LINT
- extern char loptions[];
- #endif LINT
- /* There are three general error-message functions:
- lexerror() lexical and pre-processor error messages
- error() syntactic and semantic error messages
- expr_error() errors in expressions
- The difference lies in the place where the file name and line
- number come from.
- Lexical errors report from the global variables LineNumber and
- FileName, expression errors get their information from the
- expression, whereas other errors use the information in the token.
- */
- static _error();
- /*VARARGS*/
- error(va_alist) /* fmt, args */
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- _error(ERROR, dot.tk_file, dot.tk_line, ap);
- }
- va_end(ap);
- }
- /*VARARGS*/
- expr_error(va_alist) /* expr, fmt, args */
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- register struct expr *expr = va_arg(ap, struct expr *);
- if (!(expr->ex_flags & EX_ERROR)) {
- /* to prevent proliferation */
- _error(ERROR, expr->ex_file, expr->ex_line, ap);
- expr->ex_flags |= EX_ERROR;
- }
- }
- va_end(ap);
- }
- /*VARARGS*/
- warning(va_alist) /* fmt, args */
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- _error(WARNING, dot.tk_file, dot.tk_line, ap);
- }
- va_end(ap);
- }
- /*VARARGS*/
- expr_warning(va_alist) /* expr, fmt, args */
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- struct expr *expr = va_arg(ap, struct expr *);
- if (!(expr->ex_flags & EX_ERROR)) {
- /* to prevent proliferation */
- _error(WARNING, expr->ex_file, expr->ex_line, ap);
- }
- }
- va_end(ap);
- }
- #ifdef LINT
- /*VARARGS*/
- def_warning(va_alist) /* def, fmt, args */
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- register struct def *def = va_arg(ap, struct def *);
- _error(WARNING, def->df_file, def->df_line, ap);
- }
- va_end(ap);
- }
- /*VARARGS*/
- hwarning(va_alist) /* fmt, args */
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- if (loptions['h'])
- _error(WARNING, dot.tk_file, dot.tk_line, ap);
- }
- va_end(ap);
- }
- /*VARARGS*/
- awarning(va_alist) /* fmt, args */
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- if (loptions['a'])
- _error(WARNING, dot.tk_file, dot.tk_line, ap);
- }
- va_end(ap);
- }
- #endif LINT
- /*VARARGS*/
- lexerror(va_alist) /* fmt, args */
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- _error(ERROR, FileName, LineNumber, ap);
- }
- va_end(ap);
- }
- #ifndef NOPP
- /*VARARGS*/
- lexwarning(va_alist) /* fmt, args */
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- _error(WARNING, FileName, LineNumber, ap);
- }
- va_end(ap);
- }
- #endif NOPP
- /*VARARGS*/
- crash(va_alist) /* fmt, args */
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- _error(CRASH, FileName, LineNumber, ap);
- }
- va_end(ap);
- C_close();
- #ifdef DEBUG
- sys_stop(S_ABORT);
- #else DEBUG
- sys_stop(S_EXIT);
- #endif DEBUG
- /* NOTREACHED */
- }
- /*VARARGS*/
- fatal(va_alist) /* fmt, args */
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- _error(FATAL, FileName, LineNumber, ap);
- }
- va_end(ap);
- if (C_busy()) C_close();
- sys_stop(S_EXIT);
- /*NOTREACHED*/
- }
- static
- _error(class, fn, ln, ap)
- int class;
- char *fn;
- unsigned int ln;
- va_list ap;
- {
- char *remark;
- char *fmt = va_arg(ap, char *);
- /* check visibility of message */
- switch (class) {
- case WARNING:
- case ERROR:
- if (token_nmb < tk_nmb_at_last_syn_err + ERR_SHADOW)
- /* warning or error message overshadowed */
- return;
- break;
- }
- /* Since name and number are gathered from different places
- depending on the class, we first collect the relevant
- values and then decide what to print.
- */
- /* preliminaries */
- switch (class) {
- case WARNING:
- if (options['w'])
- return;
- break;
- case ERROR:
- case CRASH:
- case FATAL:
- if (C_busy())
- C_ms_err();
- err_occurred = 1;
- break;
- }
- /* the remark */
- switch (class) {
- case WARNING:
- #ifndef LINT
- remark = "(warning)";
- #else LINT
- remark = 0;
- #endif LINT
- break;
- case ERROR:
- remark = 0;
- break;
- case CRASH:
- remark = "CRASH\007";
- break;
- case FATAL:
- remark = "fatal error --";
- break;
- default:
- /*NOTREACHED*/;
- }
-
- #ifdef LINT
- if ( /* there is a file name */
- fn
- && /* the file name is global */
- fn[0] == '/'
- && /* it is not a .c file */
- strcmp(&fn[strlen(fn)-2], ".c") != 0
- ) {
- /* we skip this message */
- return;
- }
- #endif LINT
-
- if (fn)
- fprint(ERROUT, "\"%s\", line %u: ", fn, ln);
- if (remark)
- fprint(ERROUT, "%s ", remark);
- doprnt(ERROUT, fmt, ap); /* contents of error */
- fprint(ERROUT, "\n");
- }
|