1987-03-10 17:51:10 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
|
|
*/
|
1986-03-10 13:07:55 +00:00
|
|
|
/* $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 */
|
|
|
|
|
1990-09-18 14:29:42 +00:00
|
|
|
#include "lint.h"
|
1988-04-15 15:07:51 +00:00
|
|
|
#include <varargs.h>
|
1986-03-25 10:39:23 +00:00
|
|
|
#include <system.h>
|
1990-09-18 14:29:42 +00:00
|
|
|
#ifndef LINT
|
1986-03-25 16:40:43 +00:00
|
|
|
#include <em.h>
|
1990-09-18 14:29:42 +00:00
|
|
|
#else
|
|
|
|
#include "em_lint.h"
|
|
|
|
#endif LINT
|
1986-03-25 16:40:43 +00:00
|
|
|
|
1986-03-10 13:07:55 +00:00
|
|
|
#include "nopp.h"
|
|
|
|
#include "errout.h"
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
#include "tokenname.h"
|
|
|
|
#include "arith.h"
|
|
|
|
#include "label.h"
|
|
|
|
#include "expr.h"
|
1988-08-19 13:55:22 +00:00
|
|
|
#include "def.h"
|
1986-03-10 13:07:55 +00:00
|
|
|
#include "LLlex.h"
|
|
|
|
|
1988-04-15 15:07:51 +00:00
|
|
|
/* This file contains the error-message and diagnostic
|
1986-03-10 13:07:55 +00:00
|
|
|
functions. Beware, they are called with a variable number of
|
|
|
|
arguments!
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* error classes */
|
1988-09-16 23:19:50 +00:00
|
|
|
#define WARNING 1
|
|
|
|
#define ERROR 2
|
|
|
|
#define CRASH 3
|
|
|
|
#define FATAL 4
|
1986-03-10 13:07:55 +00:00
|
|
|
|
1986-04-28 09:56:33 +00:00
|
|
|
int err_occurred = 0;
|
1986-03-10 13:07:55 +00:00
|
|
|
|
|
|
|
extern char options[];
|
1988-09-20 16:44:27 +00:00
|
|
|
#ifdef LINT
|
|
|
|
extern char loptions[];
|
|
|
|
#endif LINT
|
|
|
|
|
1986-03-10 13:07:55 +00:00
|
|
|
/* 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.
|
|
|
|
*/
|
|
|
|
|
1988-09-16 23:19:50 +00:00
|
|
|
static _error();
|
|
|
|
|
1988-08-19 13:55:22 +00:00
|
|
|
/*VARARGS*/
|
|
|
|
error(va_alist) /* fmt, args */
|
1988-04-15 15:07:51 +00:00
|
|
|
va_dcl
|
1986-03-10 13:07:55 +00:00
|
|
|
{
|
1988-04-15 15:07:51 +00:00
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
{
|
1988-09-16 23:19:50 +00:00
|
|
|
_error(ERROR, dot.tk_file, dot.tk_line, ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
}
|
1988-04-15 15:07:51 +00:00
|
|
|
va_end(ap);
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
1988-08-19 13:55:22 +00:00
|
|
|
/*VARARGS*/
|
|
|
|
expr_error(va_alist) /* expr, fmt, args */
|
1988-04-15 15:07:51 +00:00
|
|
|
va_dcl
|
1986-03-10 13:07:55 +00:00
|
|
|
{
|
1988-04-15 15:07:51 +00:00
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
{
|
|
|
|
register struct expr *expr = va_arg(ap, struct expr *);
|
|
|
|
|
|
|
|
if (!(expr->ex_flags & EX_ERROR)) {
|
|
|
|
/* to prevent proliferation */
|
1988-09-16 23:19:50 +00:00
|
|
|
_error(ERROR, expr->ex_file, expr->ex_line, ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
expr->ex_flags |= EX_ERROR;
|
|
|
|
}
|
1988-04-15 15:07:51 +00:00
|
|
|
}
|
|
|
|
va_end(ap);
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
1988-08-19 13:55:22 +00:00
|
|
|
/*VARARGS*/
|
|
|
|
warning(va_alist) /* fmt, args */
|
1988-04-15 15:07:51 +00:00
|
|
|
va_dcl
|
1986-03-10 13:07:55 +00:00
|
|
|
{
|
1988-04-15 15:07:51 +00:00
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
{
|
1988-09-16 23:19:50 +00:00
|
|
|
_error(WARNING, dot.tk_file, dot.tk_line, ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
}
|
1988-04-15 15:07:51 +00:00
|
|
|
va_end(ap);
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
1988-08-19 13:55:22 +00:00
|
|
|
/*VARARGS*/
|
|
|
|
expr_warning(va_alist) /* expr, fmt, args */
|
1988-04-15 15:07:51 +00:00
|
|
|
va_dcl
|
1986-03-10 13:07:55 +00:00
|
|
|
{
|
1988-04-15 15:07:51 +00:00
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
{
|
|
|
|
struct expr *expr = va_arg(ap, struct expr *);
|
|
|
|
|
|
|
|
if (!(expr->ex_flags & EX_ERROR)) {
|
|
|
|
/* to prevent proliferation */
|
1988-09-16 23:19:50 +00:00
|
|
|
_error(WARNING, expr->ex_file, expr->ex_line, ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
}
|
1988-04-15 15:07:51 +00:00
|
|
|
}
|
|
|
|
va_end(ap);
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
1988-09-20 16:44:27 +00:00
|
|
|
#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
|
|
|
|
|
1988-08-19 13:55:22 +00:00
|
|
|
/*VARARGS*/
|
|
|
|
lexerror(va_alist) /* fmt, args */
|
1988-04-15 15:07:51 +00:00
|
|
|
va_dcl
|
1986-03-10 13:07:55 +00:00
|
|
|
{
|
1988-04-15 15:07:51 +00:00
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
{
|
1988-09-16 23:19:50 +00:00
|
|
|
_error(ERROR, FileName, LineNumber, ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
}
|
1988-04-15 15:07:51 +00:00
|
|
|
va_end(ap);
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NOPP
|
1988-08-19 13:55:22 +00:00
|
|
|
/*VARARGS*/
|
|
|
|
lexwarning(va_alist) /* fmt, args */
|
1988-04-15 15:07:51 +00:00
|
|
|
va_dcl
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
{
|
1988-09-16 23:19:50 +00:00
|
|
|
_error(WARNING, FileName, LineNumber, ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
}
|
1988-04-15 15:07:51 +00:00
|
|
|
va_end(ap);
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|
|
|
|
#endif NOPP
|
|
|
|
|
1988-08-19 13:55:22 +00:00
|
|
|
/*VARARGS*/
|
|
|
|
crash(va_alist) /* fmt, args */
|
1988-04-15 15:07:51 +00:00
|
|
|
va_dcl
|
1986-03-10 13:07:55 +00:00
|
|
|
{
|
1988-04-15 15:07:51 +00:00
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
{
|
1988-09-16 23:19:50 +00:00
|
|
|
_error(CRASH, FileName, LineNumber, ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
}
|
1988-04-15 15:07:51 +00:00
|
|
|
va_end(ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
|
1986-03-10 13:07:55 +00:00
|
|
|
C_close();
|
|
|
|
#ifdef DEBUG
|
1986-03-25 10:39:23 +00:00
|
|
|
sys_stop(S_ABORT);
|
1986-03-10 13:07:55 +00:00
|
|
|
#else DEBUG
|
1986-03-25 10:39:23 +00:00
|
|
|
sys_stop(S_EXIT);
|
1986-03-10 13:07:55 +00:00
|
|
|
#endif DEBUG
|
1988-08-19 13:55:22 +00:00
|
|
|
/* NOTREACHED */
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
1988-08-19 13:55:22 +00:00
|
|
|
/*VARARGS*/
|
|
|
|
fatal(va_alist) /* fmt, args */
|
1988-04-15 15:07:51 +00:00
|
|
|
va_dcl
|
1986-03-10 13:07:55 +00:00
|
|
|
{
|
1988-04-15 15:07:51 +00:00
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
{
|
1988-09-16 23:19:50 +00:00
|
|
|
_error(FATAL, FileName, LineNumber, ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
}
|
1988-04-15 15:07:51 +00:00
|
|
|
va_end(ap);
|
1988-04-25 16:24:42 +00:00
|
|
|
|
|
|
|
if (C_busy()) C_close();
|
1986-03-25 10:39:23 +00:00
|
|
|
sys_stop(S_EXIT);
|
1988-09-16 23:19:50 +00:00
|
|
|
/*NOTREACHED*/
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
1988-09-16 23:19:50 +00:00
|
|
|
static
|
|
|
|
_error(class, fn, ln, ap)
|
1986-03-10 13:07:55 +00:00
|
|
|
int class;
|
1988-09-16 23:19:50 +00:00
|
|
|
char *fn;
|
|
|
|
unsigned int ln;
|
1988-04-15 15:07:51 +00:00
|
|
|
va_list ap;
|
1986-03-10 13:07:55 +00:00
|
|
|
{
|
1988-09-16 23:19:50 +00:00
|
|
|
char *remark;
|
1988-04-15 15:07:51 +00:00
|
|
|
char *fmt = va_arg(ap, char *);
|
1989-10-30 16:19:35 +00:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
1986-03-10 13:07:55 +00:00
|
|
|
/* 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) {
|
1988-09-16 23:19:50 +00:00
|
|
|
case WARNING:
|
|
|
|
if (options['w'])
|
|
|
|
return;
|
|
|
|
break;
|
|
|
|
|
1986-03-10 13:07:55 +00:00
|
|
|
case ERROR:
|
|
|
|
case CRASH:
|
|
|
|
case FATAL:
|
|
|
|
if (C_busy())
|
|
|
|
C_ms_err();
|
|
|
|
err_occurred = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* the remark */
|
|
|
|
switch (class) {
|
|
|
|
case WARNING:
|
1988-09-20 16:44:27 +00:00
|
|
|
#ifndef LINT
|
1986-03-10 13:07:55 +00:00
|
|
|
remark = "(warning)";
|
1988-09-20 16:44:27 +00:00
|
|
|
#else LINT
|
|
|
|
remark = 0;
|
|
|
|
#endif LINT
|
1986-03-10 13:07:55 +00:00
|
|
|
break;
|
1988-09-16 23:19:50 +00:00
|
|
|
|
|
|
|
case ERROR:
|
|
|
|
remark = 0;
|
|
|
|
break;
|
|
|
|
|
1986-03-10 13:07:55 +00:00
|
|
|
case CRASH:
|
|
|
|
remark = "CRASH\007";
|
|
|
|
break;
|
1988-09-16 23:19:50 +00:00
|
|
|
|
1986-03-10 13:07:55 +00:00
|
|
|
case FATAL:
|
|
|
|
remark = "fatal error --";
|
|
|
|
break;
|
1988-09-16 23:19:50 +00:00
|
|
|
default:
|
|
|
|
/*NOTREACHED*/;
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
1988-09-20 16:44:27 +00:00
|
|
|
#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
|
1986-03-10 13:07:55 +00:00
|
|
|
|
|
|
|
if (fn)
|
1986-04-03 14:32:56 +00:00
|
|
|
fprint(ERROUT, "\"%s\", line %u: ", fn, ln);
|
1986-03-10 13:07:55 +00:00
|
|
|
if (remark)
|
1986-04-03 14:32:56 +00:00
|
|
|
fprint(ERROUT, "%s ", remark);
|
1988-04-15 15:07:51 +00:00
|
|
|
doprnt(ERROUT, fmt, ap); /* contents of error */
|
1986-04-03 14:32:56 +00:00
|
|
|
fprint(ERROUT, "\n");
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|