Parcourir la source

error messages and error handling

dick il y a 36 ans
Parent
commit
fe62ccb08d

+ 12 - 0
lang/cem/cemcom/.distr

@@ -7,6 +7,7 @@ LLlex.h
 LLmessage.c
 SmallPars
 BigPars
+LintPars
 align.h
 arith.c
 arith.h
@@ -87,3 +88,14 @@ type.c
 type.str
 util.str
 util.c
+acklint
+l_class.h
+l_comment.c
+l_ev_ord.c
+l_lint.c
+l_lint.h
+l_misc.c
+l_outdef.c
+l_outdef.str
+l_state.str
+l_states.c

+ 2 - 2
lang/cem/cemcom/LLlex.c

@@ -234,8 +234,8 @@ firstline:
 				LoadChar(ch);
 				if (ch != nch) {
 					PushBack();
-					lexerror("illegal combination '=%c'",
-						nch);
+					lexerror("illegal operator '=%c%c'",
+						nch, ch);
 				}
 				return ptok->tk_symb = 
 					nch == '<' ? LEFTAB : RIGHTAB;

+ 0 - 1
lang/cem/cemcom/arith.c

@@ -11,7 +11,6 @@
 	semantics of C is a mess.
 */
 
-#include	"botch_free.h"
 #include	<alloc.h>
 #include	"nofloat.h"
 #include	"nobitfield.h"

+ 3 - 1
lang/cem/cemcom/ch7.c

@@ -207,8 +207,10 @@ ch7cast(expp, oper, tp)
 		else		/* !oldi && !i */
 			float2float(expp, tp);
 #else NOFLOAT
-		else
+		else {
 			crash("(ch7cast) floats not implemented\n");
+			/*NOTREACHED*/
+		}
 #endif NOFLOAT
 	}
 	else

+ 1 - 0
lang/cem/cemcom/ch7bin.c

@@ -35,6 +35,7 @@ ch7bin(expp, oper, expr)
 	/*	apply binary operator oper between *expp and expr.
 		NB: don't swap operands if op is one of the op= operators!!!
 	*/
+
 	any2opnd(expp, oper);
 	any2opnd(&expr, oper);
 	switch (oper)	{

+ 2 - 2
lang/cem/cemcom/ch7mon.c

@@ -53,12 +53,12 @@ ch7mon(oper, expp)
 		break;
 	case '&':
 		if ((*expp)->ex_type->tp_fund == ARRAY) {
-			warning("& before array: ignored");
+			warning("& before array ignored");
 			array2pointer(*expp);
 		}
 		else
 		if ((*expp)->ex_type->tp_fund == FUNCTION) {
-			warning("& before function: ignored");
+			warning("& before function ignored");
 			function2pointer(*expp);
 		}
 		else

+ 4 - 5
lang/cem/cemcom/code.c

@@ -29,7 +29,6 @@
 #include	"assert.h"
 #include	"noRoption.h"
 #include	"file_info.h"
-
 label lab_count = 1;
 label datlab_count = 1;
 
@@ -48,7 +47,7 @@ static int	pro_id;
 #endif USE_TMP
 
 extern char options[];
-char *symbol2str();
+extern char *symbol2str();
 
 init_code(dst_file)
 	char *dst_file;
@@ -65,7 +64,6 @@ init_code(dst_file)
 	C_insertpart(tmp_id = C_getid());
 #endif	USE_TMP
 }
-
 static struct string_cst *str_list = 0;
 
 code_string(val, len, dlb)
@@ -425,7 +423,7 @@ code_declaration(idf, expr, lvl, sc)
 			break;
 		default:
 			crash("bad local storage class");
-			break;
+			/*NOTREACHED*/
 		}
 	}
 }
@@ -446,7 +444,8 @@ loc_init(expr, id)
 	case ARRAY:
 	case STRUCT:
 	case UNION:
-		error("no automatic aggregate initialisation");
+		error("automatic %s cannot be initialized in declaration",
+			symbol2str(tp->tp_fund));
 		free_expression(e);
 		return;
 	}

+ 1 - 0
lang/cem/cemcom/conversion.c

@@ -102,6 +102,7 @@ conversion(from_type, to_type)
 #endif NOFLOAT
 	default:
 		crash("(conversion) illegal type conversion");
+		/*NOTREACHED*/
 	}
 	if ((int)(to_type->tp_size) < (int)word_size
 #ifndef NOFLOAT

+ 0 - 1
lang/cem/cemcom/declar.g

@@ -24,7 +24,6 @@
 #include	"expr.h"
 #include	"sizes.h"
 #include	"level.h"
-
 extern char options[];
 }
 

+ 2 - 2
lang/cem/cemcom/declarator.c

@@ -97,12 +97,12 @@ check_array_subscript(expr)
 	arith size = expr->VL_VALUE;
 
 	if (size < 0)	{
-		error("negative number of array elements");
+		error("array size is negative");
 		expr->VL_VALUE = (arith)1;
 	}
 	else
 	if (size == 0) {
-		warning("empty array declaration");
+		warning("array size is 0");
 	}
 	else
 	if (size & ~max_unsigned) {	/* absolutely ridiculous */

+ 2 - 2
lang/cem/cemcom/decspecs.c

@@ -6,6 +6,7 @@
 /*	D E C L A R A T I O N   S P E C I F I E R   C H E C K I N G	*/
 
 #include	"nofloat.h"
+#include	"assert.h"
 #include	"Lpars.h"
 #include	"decspecs.h"
 #include	"arith.h"
@@ -28,8 +29,7 @@ do_decspecs(ds)
 	*/
 	register struct type *tp = ds->ds_type;
 	
-	if (level == L_FORMAL1)
-		crash("do_decspecs");
+	ASSERT(level != L_FORMAL1);
 	
 	if (	level == L_GLOBAL &&
 		(ds->ds_sc == AUTO || ds->ds_sc == REGISTER)

+ 1 - 1
lang/cem/cemcom/def.str

@@ -20,7 +20,7 @@ struct def	{		/* for ordinary tags */
 	char df_alloc;		/* 0, ALLOC_SEEN or ALLOC_DONE */
 	char df_used;		/* set if idf is used */
 	char *df_file;		/* file containing the definition */
-	long df_line;		/* line number of the definition */
+	unsigned int df_line;	/* line number of the definition */
 	char df_formal_array;	/* to warn if sizeof is taken */
 	arith df_address;
 };

+ 33 - 45
lang/cem/cemcom/error.c

@@ -26,18 +26,14 @@
 */
 
 /* error classes */
-#define	ERROR		1
-#define	WARNING		2
-#define	LEXERROR	3
-#define	LEXWARNING	4
-#define	CRASH		5
-#define	FATAL		6
+#define	WARNING		1
+#define	ERROR		2
+#define	CRASH		3
+#define	FATAL		4
 
 int err_occurred = 0;
 
-extern char *symbol2str();
 extern char options[];
-
 /*	There are three general error-message functions:
 		lexerror()	lexical and pre-processor error messages
 		error()		syntactic and semantic error messages
@@ -49,6 +45,8 @@ extern char options[];
 	expression, whereas other errors use the information in the token.
 */
 
+static _error();
+
 /*VARARGS*/
 error(va_alist)				/* fmt, args */
 	va_dcl
@@ -57,7 +55,7 @@ error(va_alist)				/* fmt, args */
 
 	va_start(ap);
 	{
-		_error(ERROR, NILEXPR, ap);
+		_error(ERROR, dot.tk_file, dot.tk_line, ap);
 	}
 	va_end(ap);
 }
@@ -74,7 +72,7 @@ expr_error(va_alist)			/* expr, fmt, args */
 
 		if (!(expr->ex_flags & EX_ERROR)) {
 			/* to prevent proliferation */
-			_error(ERROR, expr, ap);
+			_error(ERROR, expr->ex_file, expr->ex_line, ap);
 			expr->ex_flags |= EX_ERROR;
 		}
 	}
@@ -89,7 +87,7 @@ warning(va_alist)			/* fmt, args */
 
 	va_start(ap);
 	{
-		_error(WARNING, NILEXPR, ap);
+		_error(WARNING, dot.tk_file, dot.tk_line, ap);
 	}
 	va_end(ap);
 }
@@ -106,7 +104,7 @@ expr_warning(va_alist)			/* expr, fmt, args */
 
 		if (!(expr->ex_flags & EX_ERROR)) {
 			/* to prevent proliferation */
-			_error(WARNING, expr, ap);
+			_error(WARNING, expr->ex_file, expr->ex_line, ap);
 		}
 	}
 	va_end(ap);
@@ -120,7 +118,7 @@ lexerror(va_alist)			/* fmt, args */
 
 	va_start(ap);
 	{
-		_error(LEXERROR, NILEXPR, ap);
+		_error(ERROR, FileName, LineNumber, ap);
 	}
 	va_end(ap);
 }
@@ -134,7 +132,7 @@ lexwarning(va_alist)			/* fmt, args */
 
 	va_start(ap);
 	{
-		_error(LEXWARNING, NILEXPR, ap);
+		_error(WARNING, FileName, LineNumber, ap);
 	}
 	va_end(ap);
 }
@@ -148,7 +146,7 @@ crash(va_alist)				/* fmt, args */
 
 	va_start(ap);
 	{
-		_error(CRASH, NILEXPR, ap);
+		_error(CRASH, FileName, LineNumber, ap);
 	}
 	va_end(ap);
 
@@ -169,17 +167,20 @@ fatal(va_alist)				/* fmt, args */
 
 	va_start(ap);
 	{
-		_error(FATAL, NILEXPR, ap);
+		_error(FATAL, FileName, LineNumber, ap);
 	}
 	va_end(ap);
 
 	if (C_busy()) C_close();
 	sys_stop(S_EXIT);
+	/*NOTREACHED*/
 }
 
-_error(class, expr, ap)
+static
+_error(class, fn, ln, ap)
 	int class;
-	struct expr *expr;
+	char *fn;
+	unsigned int ln;
 	va_list ap;
 {
 	/*	_error attempts to limit the number of error messages
@@ -188,9 +189,7 @@ _error(class, expr, ap)
 	static char *last_fn = 0;
 	static unsigned int last_ln = 0;
 	static int e_seen = 0;
-	char *fn = 0;
-	unsigned int ln = 0;
-	char *remark = 0;
+	char *remark;
 	char *fmt = va_arg(ap, char *);
 	
 	/*	Since name and number are gathered from different places
@@ -199,50 +198,39 @@ _error(class, expr, ap)
 	*/
 	/* preliminaries */
 	switch (class)	{
+	case WARNING:
+		if (options['w'])
+			return;
+		break;
+
 	case ERROR:
-	case LEXERROR:
 	case CRASH:
 	case FATAL:
 		if (C_busy())
 			C_ms_err();
 		err_occurred = 1;
 		break;
-	
-	case WARNING:
-	case LEXWARNING:
-		if (options['w'])
-			return;
-		break;
 	}
 
 	/* the remark */
 	switch (class)	{	
 	case WARNING:
-	case LEXWARNING:
 		remark = "(warning)";
 		break;
+
+	case ERROR:
+		remark = 0;
+		break;
+
 	case CRASH:
 		remark = "CRASH\007";
 		break;
+
 	case FATAL:
 		remark = "fatal error --";
 		break;
-	}
-	
-	/* the place */
-	switch (class)	{	
-	case WARNING:
-	case ERROR:
-		fn = expr ? expr->ex_file : dot.tk_file;
-		ln = expr ? expr->ex_line : dot.tk_line;
-		break;
-	case LEXWARNING:
-	case LEXERROR:
-	case CRASH:
-	case FATAL:
-		fn = FileName;
-		ln = LineNumber;
-		break;
+	default:
+		/*NOTREACHED*/;
 	}
 	
 	if (ln == last_ln && fn && last_fn && strcmp(fn, last_fn) == 0)	{

+ 3 - 2
lang/cem/cemcom/eval.c

@@ -904,16 +904,17 @@ load_val(expr, rlval)
 	}
 	else {
 		register struct idf *id = expr->VL_IDF;
-		register struct def *df;
+		register struct def *df = id->id_def;
 
 		ASSERT(expr->VL_CLASS == Name);
-		if ((df = id->id_def)->df_type->tp_fund == FUNCTION)
+		if (df->df_type->tp_fund == FUNCTION) {
 			/*	the previous statement tried to catch a function
 				identifier, which may be cast to a pointer to a
 				function.
 				ASSERT(!(rvalue)); ???
 			*/
 			C_lpi(id->id_text);
+		}
 		else
 		if (df->df_level == L_GLOBAL) {
 			if (rvalue) {

+ 2 - 1
lang/cem/cemcom/expr.c

@@ -149,7 +149,7 @@ dot2expr(expp)
 #endif NOFLOAT
 	default:
 		crash("bad conversion to expression");
-		break;
+		/*NOTREACHED*/
 	}
 }
 
@@ -304,6 +304,7 @@ fill_int_expr(ex, ivalue, fund)
 		break;
 	default:
 		crash("(intexpr) bad fund %s\n", symbol2str(fund));
+		/*NOTREACHED*/
 	}
 	ex->ex_class = Value;
 	ex->VL_CLASS = Const;

+ 6 - 6
lang/cem/cemcom/idf.c

@@ -246,7 +246,7 @@ declare_idf(ds, dc, lvl)
 			sc = GLOBAL;
 		else
 		if (sc == REGISTER) {
-			error("function has illegal storage class");
+			error("function storage class cannot be register");
 			ds->ds_sc = sc = GLOBAL;
 		}
 	}
@@ -444,7 +444,7 @@ global_redecl(idf, new_sc, tp)
 			break;
 		default:
 			crash("bad storage class");
-			break;
+			/*NOTREACHED*/
 		}
 		break;
 	case GLOBAL:
@@ -469,7 +469,7 @@ global_redecl(idf, new_sc, tp)
 			break;
 		default:
 			crash("bad storage class");
-			break;
+			/*NOTREACHED*/
 		}
 		break;
 	case STATIC:
@@ -492,7 +492,7 @@ global_redecl(idf, new_sc, tp)
 			break;
 		default:
 			crash("bad storage class");
-			break;
+			/*NOTREACHED*/
 		}
 		break;
 	case IMPLICIT:
@@ -511,7 +511,7 @@ global_redecl(idf, new_sc, tp)
 			break;
 		default:
 			crash("bad storage class");
-			break;
+			/*NOTREACHED*/
 		}
 		break;
 	case ENUM:
@@ -520,7 +520,7 @@ global_redecl(idf, new_sc, tp)
 		break;
 	default:
 		crash("bad storage class");
-		break;
+		/*NOTREACHED*/
 	}
 }
 

+ 2 - 2
lang/cem/cemcom/idf.str

@@ -34,8 +34,8 @@ struct idf	{
 	int id_resmac;		/* if nonzero: keyword of macroproc. 	*/
 #endif NOPP
 	int id_reserved;	/* non-zero for reserved words		*/
-	char *id_file;		/* used for warnings */
-	long id_line;
+	char *id_file;		/* file containing the occurrence */
+	unsigned int id_line;	/* line number of the occurrence */
 	struct def *id_def;	/* variables, typedefs, enum-constants	*/
 	struct sdef *id_sdef;	/* selector tags			*/
 	struct tag *id_struct;	/* struct and union tags		*/

+ 1 - 1
lang/cem/cemcom/ival.g

@@ -27,7 +27,6 @@
 #include	"noRoption.h"
 #include	"estack.h"
 #include	"code.h"
-
 #define con_nullbyte()	C_con_ucon("0", (arith)1)
 #define aggregate_type(tp) ((tp)->tp_fund == ARRAY || (tp)->tp_fund == STRUCT)
 
@@ -530,6 +529,7 @@ check_ival(expp, tp)
 		break;
 	default:
 		crash("check_ival");
+		/*NOTREACHED*/
 	}
 }
 

+ 6 - 7
lang/cem/cemcom/main.c

@@ -118,7 +118,8 @@ main(argc, argv)
 	hash_stat();
 #endif	DEBUG
 
-	exit(err_occurred);
+	sys_stop(err_occurred ? S_EXIT : S_END);
+	/*NOTREACHED*/
 }
 
 char *source = 0;
@@ -130,7 +131,6 @@ compile(argc, argv)
 {
 	char *result;
 	register char *destination = 0;
-
 #ifdef DEBUG
 #ifndef NOPP
 	int pp_only = options['E'] || options['P'] || options['C'];
@@ -146,6 +146,7 @@ compile(argc, argv)
 #endif
 			fatal("%s: destination file not specified", prog_name);
 		break;
+
 	case 2:
 		destination = argv[1];
 		break;
@@ -157,6 +158,7 @@ compile(argc, argv)
 		fatal("use: %s source destination [namelist]", prog_name);
 		break;
 	}
+
 	if (strcmp(argv[0], "-"))
 		FileName = source = argv[0];
 	else {
@@ -164,8 +166,6 @@ compile(argc, argv)
 		FileName = "standard input";
 	}
 
-	if (destination && strcmp(destination, "-") == 0)
-		destination = 0;
 	if (!InsertFile(source, (char **) 0, &result)) /* read the source file	*/
 		fatal("%s: no source file %s\n", prog_name, FileName);
 	File_Inserted = 1;
@@ -185,9 +185,8 @@ compile(argc, argv)
 #endif NOPP
 #endif DEBUG
 	{
-
-		init_code(destination);
-
+		init_code(destination && strcmp(destination, "-") != 0 ?
+					destination : 0);
 		/* compile the source text			*/
 		C_program();
 

+ 11 - 7
lang/cem/cemcom/options.c

@@ -31,21 +31,26 @@ extern int inc_total;
 char options[128];			/* one for every char	*/
 extern int idfsize;
 
-int txt2int();
+static int txt2int();
 
 do_option(text)
 	char *text;
 {
 	register char opt;
 
+next_option:			/* to allow combined one-char options */
 	switch (opt = *text++)	{
 
+	case 0:			/* to end the goto next_option loop */
+		break;
+
 	default:
 		fatal("illegal option: %c", opt);
 		break;
+
 	case '-':
-		options[*text] = 1;	/* flags, debug options etc.	*/
-		break;
+		options[*text++] = 1;	/* flags, debug options etc.	*/
+		goto next_option;
 
 #ifdef	DATAFLOW
 	case 'd':
@@ -58,12 +63,11 @@ do_option(text)
 	case 'R':			/* strict version */
 #endif
 		options[opt] = 1;
-		break;
-
+		goto next_option;
 #ifdef	NOROPTION
 	case 'R':
 		warning("-R option not implemented");
-		break;
+		goto next_option;
 #endif
 
 #ifdef	___XXX___
@@ -293,7 +297,7 @@ deleted, is now a debug-flag
 	}
 }
 
-int
+static int
 txt2int(tp)
 	register char **tp;
 {

+ 0 - 1
lang/cem/cemcom/program.g

@@ -56,7 +56,6 @@
 #include	"code.h"
 #include	"expr.h"
 #include	"def.h"
-
 #ifndef NOPP
 extern arith ifval;
 #endif NOPP

+ 1 - 0
lang/cem/cemcom/replace.c

@@ -137,6 +137,7 @@ macro_func(idef)
 		break;
 	default :
 		crash("(macro_func)");
+		/*NOTREACHED*/
 	}
 }
 

+ 1 - 1
lang/cem/cemcom/scan.c

@@ -181,7 +181,7 @@ copyact(ch1, ch2, lvl)
 				copy(EOS);
 
 				if (++nr_of_params >= NPARAMS) {
-					fatal("(getact) too many actuals");
+					fatal("too many actual parameters");
 				}
 
 				actparams[nr_of_params] = aptr;

+ 1 - 0
lang/cem/cemcom/stack.c

@@ -95,6 +95,7 @@ unstack_level()
 	if (options['t'])
 		dumpidftab("before unstackidfs", 0);
 #endif	DEBUG
+
 	/*	The implementation below is more careful than strictly
 		necessary. Optimists may optimize it afterwards.
 	*/

+ 4 - 4
lang/cem/cemcom/statement.g

@@ -20,7 +20,6 @@
 #include	"code.h"
 #include	"stack.h"
 #include	"def.h"
-
 extern int level;
 }
 
@@ -76,6 +75,7 @@ statement
 	asm_statement
 ;
 
+
 expression_statement
 	{	struct expr *expr;
 	}
@@ -84,7 +84,7 @@ expression_statement
 	';'
 		{
 #ifdef	DEBUG
-			print_expr("Full expression", expr);
+			print_expr("expression_statement", expr);
 #endif	DEBUG
 			code_expr(expr, RVAL, FALSE, NO_LABEL, NO_LABEL);
 			free_expression(expr);
@@ -267,8 +267,8 @@ for_statement
 	';'
 	expression(&e_incr)?
 	')'
-	{
-	}
+		{
+		}
 	statement
 		{
 			C_df_ilb(l_continue);

+ 1 - 1
lang/cem/cemcom/struct.c

@@ -404,7 +404,7 @@ add_field(szp, fd, fdtpp, idf, stp)
 
 	default:
 		/* wrong type altogether */
-		error("illegal field type (%s)",
+		error("field type cannot be %s",
 				symbol2str((*fdtpp)->tp_fund));
 		*fdtpp = error_type;
 		return field_offset;

+ 9 - 6
lang/cem/cemcom/switch.c

@@ -213,11 +213,14 @@ code_default()
 {
 	register struct switch_hdr *sh = switch_stack;
 
-	if (sh == 0)
-		error("default not in switch");
-	else
-	if (sh->sh_default != 0)
+	if (sh == 0) {
+		error("default statement not in switch");
+		return;
+	}
+	if (sh->sh_default != 0) {
 		error("multiple entry for default in switch");
-	else
-		C_df_ilb(sh->sh_default = text_label());
+		return;
+	}
+
+	C_df_ilb(sh->sh_default = text_label());
 }