Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251
WebSVN – tendra.SVN – Diff – /trunk/src/producers/common/utility/error.c – Rev 2 and 7

Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
29
 
59
 
30
 
60
 
31
#include "config.h"
61
#include "config.h"
32
#if FS_STDARG
62
#if FS_STDARG
33
#include <stdarg.h>
63
#include <stdarg.h>
34
#else
64
#else
35
#include <varargs.h>
65
#include <varargs.h>
Line 57... Line 87...
57
#include "save.h"
87
#include "save.h"
58
#include "statement.h"
88
#include "statement.h"
59
#include "ustring.h"
89
#include "ustring.h"
60
#include "xalloc.h"
90
#include "xalloc.h"
61
 
91
 
62
 
92
 
63
/*
93
/*
64
    PROGRAM NAME
94
    PROGRAM NAME
65
 
95
 
66
    These variables give the program name and version number.
96
    These variables give the program name and version number.
67
*/
97
*/
68
 
98
 
69
CONST char *progname = NULL ;
99
CONST char *progname = NULL;
70
CONST char *progvers = NULL ;
100
CONST char *progvers = NULL;
71
 
101
 
72
 
102
 
73
/*
103
/*
74
    SET PROGRAM NAME
104
    SET PROGRAM NAME
75
 
105
 
76
    This routine sets the program name to the basename of prog and the
106
    This routine sets the program name to the basename of prog and the
77
    program version to vers.
107
    program version to vers.
78
*/
108
*/
79
 
109
 
80
void set_progname
110
void
81
    PROTO_N ( ( prog, vers ) )
-
 
82
    PROTO_T ( CONST char *prog X CONST char *vers )
111
set_progname(CONST char *prog, CONST char *vers)
83
{
112
{
84
    error_file = stderr ;
113
	error_file = stderr;
85
    if ( prog ) {
114
	if (prog) {
86
	char *s = strrchr ( prog, '/' ) ;
115
		char *s = strrchr(prog, '/');
87
	if ( s ) prog = s + 1 ;
116
		if (s)prog = s + 1;
88
	s = strrchr ( prog, file_sep ) ;
117
		s = strrchr(prog, file_sep);
89
	if ( s ) prog = s + 1 ;
118
		if (s)prog = s + 1;
90
	progname = prog ;
119
		progname = prog;
91
    } else {
120
	} else {
92
	progname = "unknown" ;
121
		progname = "unknown";
93
    }
122
	}
94
    progvers = vers ;
123
	progvers = vers;
95
    return ;
124
	return;
96
}
125
}
97
 
126
 
98
 
127
 
99
/*
128
/*
100
    PRINT VERSION NUMBER
129
    PRINT VERSION NUMBER
101
 
130
 
102
    This routine prints the program name and version number plus the
131
    This routine prints the program name and version number plus the
103
    versions of C++ and the TDF specification it supports to the print
132
    versions of C++ and the TDF specification it supports to the print
104
    buffer, returning the result.
133
    buffer, returning the result.
105
*/
134
*/
106
 
135
 
107
string report_version
136
string
108
    PROTO_N ( ( vers ) )
-
 
109
    PROTO_T ( int vers )
137
report_version(int vers)
110
{
138
{
111
    BUFFER *bf = clear_buffer ( &print_buff, NIL ( FILE ) ) ;
139
	BUFFER *bf = clear_buffer(&print_buff, NIL(FILE));
112
    bfprintf ( bf, "%x: Version %x", progname, progvers ) ;
140
	bfprintf(bf, "%x: Version %x", progname, progvers);
113
    if ( vers ) {
141
	if (vers) {
114
	char buff [20] ;
142
		char buff[20];
115
	char *v = LANGUAGE_VERSION ;
143
		char *v = LANGUAGE_VERSION;
116
	sprintf_v ( buff, "%.4s-%.2s", v, v + 4 ) ;
144
		sprintf_v(buff, "%.4s-%.2s", v, v + 4);
117
	bfprintf ( bf, " (%x %x", LANGUAGE_NAME, buff ) ;
145
		bfprintf(bf, " (%x %x", LANGUAGE_NAME, buff);
118
	bfprintf ( bf, " to TDF %d.%d", TDF_major, TDF_minor ) ;
146
		bfprintf(bf, " to TDF %d.%d", TDF_major, TDF_minor);
119
#ifdef RELEASE
147
#ifdef RELEASE
120
	bfprintf ( bf, ", Release %x", RELEASE ) ;
148
		bfprintf(bf, ", Release %x", RELEASE);
121
#endif
149
#endif
122
	bfprintf ( bf, ")" ) ;
150
		bfprintf(bf, ")");
123
    }
151
	}
124
    return ( bf->start ) ;
152
	return (bf->start);
125
}
153
}
126
 
154
 
127
 
155
 
128
/*
156
/*
129
    CURRENT FILE POSITION
157
    CURRENT FILE POSITION
130
 
158
 
131
    This structure gives the current file position.  This consists of a
159
    This structure gives the current file position.  This consists of a
132
    string, giving the file name, an integer, giving the line number, and
160
    string, giving the file name, an integer, giving the line number, and
133
    a pointer to any previous positions from which this is derived by a
161
    a pointer to any previous positions from which this is derived by a
134
    #include directive.
162
    #include directive.
135
*/
163
*/
136
 
164
 
137
LOCATION crt_loc = NULL_loc ;
165
LOCATION crt_loc = NULL_loc;
138
LOCATION builtin_loc = NULL_loc ;
166
LOCATION builtin_loc = NULL_loc;
139
 
167
 
140
 
168
 
141
/*
169
/*
142
    ERROR REPORTING VARIABLES
170
    ERROR REPORTING VARIABLES
143
 
171
 
144
    These variables are used by the error reporting routines.  exit_status
172
    These variables are used by the error reporting routines.  exit_status
145
    gives the overall status of the program - it is EXIT_SUCCESS if no
173
    gives the overall status of the program - it is EXIT_SUCCESS if no
146
    serious errors have occurred, and EXIT_FAILURE otherwise.  A count of
174
    serious errors have occurred, and EXIT_FAILURE otherwise.  A count of
147
    the number of serious errors is kept in number_errors, up to a maximum
175
    the number of serious errors is kept in number_errors, up to a maximum
148
    of max_errors.
176
    of max_errors.
149
*/
177
*/
150
 
178
 
151
FILE *error_file = NULL ;
179
FILE *error_file = NULL;
152
int exit_status = EXIT_SUCCESS ;
180
int exit_status = EXIT_SUCCESS;
153
unsigned long number_errors = 0 ;
181
unsigned long number_errors = 0;
154
unsigned long number_warnings = 0 ;
182
unsigned long number_warnings = 0;
155
unsigned long max_errors = 32 ;
183
unsigned long max_errors = 32;
156
int error_threshold = ERROR_NONE ;
184
int error_threshold = ERROR_NONE;
157
int no_error_args = 0 ;
185
int no_error_args = 0;
158
int verbose = 0 ;
186
int verbose = 0;
159
static int print_short = 0 ;
187
static int print_short = 0;
160
static int print_error_loc = 0 ;
188
static int print_error_loc = 0;
161
static int print_error_name = 0 ;
189
static int print_error_name = 0;
162
static int print_error_source = 0 ;
190
static int print_error_source = 0;
163
static int print_iso_ref = 1 ;
191
static int print_iso_ref = 1;
164
static int print_ansi_ref = 0 ;
192
static int print_ansi_ref = 0;
165
 
193
 
166
 
194
 
167
/*
195
/*
168
    PROCESS AN ERROR FORMATTING OPTION
196
    PROCESS AN ERROR FORMATTING OPTION
169
 
197
 
170
    This routine processes the error formatting options given by opt.
198
    This routine processes the error formatting options given by opt.
171
    This corresponds to the command-line option '-mopt'.
199
    This corresponds to the command-line option '-mopt'.
172
*/
200
*/
173
 
201
 
174
void error_option
202
void
175
    PROTO_N ( ( opt ) )
-
 
176
    PROTO_T ( string opt )
203
error_option(string opt)
177
{
204
{
178
    int out = 1 ;
205
	int out = 1;
179
    character c ;
206
	character c;
180
    while ( c = *( opt++ ), c != 0 ) {
207
	while (c = *(opt++), c != 0) {
181
	switch ( c ) {
208
		switch (c) {
-
 
209
		case 'a':
182
	    case 'a' : print_ansi_ref = out ; break ;
210
			print_ansi_ref = out;
-
 
211
			break;
-
 
212
		case 'c':
183
	    case 'c' : print_error_source = out ; break ;
213
			print_error_source = out;
-
 
214
			break;
-
 
215
		case 'e':
184
	    case 'e' : print_error_name = out ; break ;
216
			print_error_name = out;
-
 
217
			break;
-
 
218
		case 'f':
185
	    case 'f' : good_fseek = out ; break ;
219
			good_fseek = out;
-
 
220
			break;
-
 
221
		case 'g':
186
	    case 'g' : record_location = out ; break ;
222
			record_location = out;
-
 
223
			break;
-
 
224
		case 'i':
187
	    case 'i' : good_stat = out ; break ;
225
			good_stat = out;
-
 
226
			break;
-
 
227
		case 'k':
188
	    case 'k' : output_spec = out ; break ;
228
			output_spec = out;
-
 
229
			break;
-
 
230
		case 'l':
189
	    case 'l' : print_error_loc = out ; break ;
231
			print_error_loc = out;
-
 
232
			break;
-
 
233
		case 'm':
190
	    case 'm' : allow_multibyte = out ; break ;
234
			allow_multibyte = out;
-
 
235
			break;
-
 
236
		case 'p':
191
	    case 'p' : preproc_space = out ; break ;
237
			preproc_space = out;
-
 
238
			break;
-
 
239
		case 'q':
192
	    case 'q' : print_short = out ; break ;
240
			print_short = out;
-
 
241
			break;
-
 
242
		case 'r':
193
	    case 'r' : allow_dos_newline = out ; break ;
243
			allow_dos_newline = out;
-
 
244
			break;
-
 
245
		case 's':
194
	    case 's' : print_iso_ref = out ; break ;
246
			print_iso_ref = out;
-
 
247
			break;
-
 
248
		case 't':
195
	    case 't' : print_type_alias = out ; break ;
249
			print_type_alias = out;
-
 
250
			break;
-
 
251
		case 'x':
196
	    case 'x' : print_c_style = out ; break ;
252
			print_c_style = out;
-
 
253
			break;
197
	    case '+' : out = 1 ; break ;
254
		case '+':
-
 
255
			out = 1;
-
 
256
			break;
198
	    case '-' : out = 0 ; break ;
257
		case '-':
-
 
258
			out = 0;
-
 
259
			break;
199
	    case 'o' : {
260
		case 'o': {
200
		error_file = ( out ? stdout : stderr ) ;
261
			error_file = (out ? stdout : stderr);
201
		break ;
262
			break;
202
	    }
263
		}
203
	    case 'w' : {
264
		case 'w': {
204
		OPTION sev = OPTION_WARN ;
265
			OPTION sev = OPTION_WARN;
-
 
266
			if (out) {
205
		if ( out ) sev = OPTION_OFF ;
267
				sev = OPTION_OFF;
-
 
268
			}
206
		OPT_CATALOG [ OPT_warning ].def [0] = sev ;
269
			OPT_CATALOG[OPT_warning].def[0] = sev;
207
		OPT_CATALOG [ OPT_warning ].def [1] = sev ;
270
			OPT_CATALOG[OPT_warning].def[1] = sev;
208
		break ;
271
			break;
209
	    }
272
		}
210
	    case 'z' : {
273
		case 'z': {
211
		OPTION sev = OPTION_ON ;
274
			OPTION sev = OPTION_ON;
-
 
275
			if (out) {
212
		if ( out ) sev = OPTION_WARN ;
276
				sev = OPTION_WARN;
-
 
277
			}
213
		OPT_CATALOG [ OPT_error ].def [0] = sev ;
278
			OPT_CATALOG[OPT_error].def[0] = sev;
214
		OPT_CATALOG [ OPT_error ].def [1] = sev ;
279
			OPT_CATALOG[OPT_error].def[1] = sev;
215
		break ;
280
			break;
216
	    }
281
		}
217
	    default : {
282
		default : {
218
		/* Unknown output options */
283
			/* Unknown output options */
-
 
284
			CONST char *err =
219
		CONST char *err = "Unknown error formatting option, '%c'" ;
285
			    "Unknown error formatting option, '%c'";
220
		error ( ERROR_WARNING, err, ( int ) c ) ;
286
			error(ERROR_WARNING, err,(int)c);
221
		break ;
287
			break;
222
	    }
288
		}
223
	}
289
		}
224
    }
290
	}
225
    return ;
291
	return;
226
}
292
}
227
 
293
 
228
 
294
 
229
/*
295
/*
230
    ERROR MESSAGE PARAMETERS
296
    ERROR MESSAGE PARAMETERS
231
 
297
 
232
    These macros are used to parameterise the form of the error messages.
298
    These macros are used to parameterise the form of the error messages.
233
*/
299
*/
Line 235... Line 301...
235
#define HEADER_FATAL		"Fatal error"
301
#define HEADER_FATAL		"Fatal error"
236
#define HEADER_SERIOUS		"Error"
302
#define HEADER_SERIOUS		"Error"
237
#define HEADER_WARNING		"Warning"
303
#define HEADER_WARNING		"Warning"
238
#define HEADER_INTERNAL		"Internal error"
304
#define HEADER_INTERNAL		"Internal error"
239
#define HEADER_ASSERT		"Assertion"
305
#define HEADER_ASSERT		"Assertion"
240
 
306
 
241
#define PRINT_HEADER( M, L, F )\
307
#define PRINT_HEADER(M, L, F)\
242
	print_location ( ( L ), ( F ) ) ;\
308
	print_location((L), (F));\
243
	fputs_v ( ": ", ( F ) ) ;\
309
	fputs_v(": ",(F));\
244
	fputs_v ( ( M ), ( F ) ) ;\
310
	fputs_v((M), (F));\
245
	fputs_v ( ":\n", ( F ) )
311
	fputs_v(":\n",(F))
246
 
312
 
247
#define PRINT_SOURCE( L, F )\
313
#define PRINT_SOURCE(L, F)\
248
	print_source ( ( L ), 1, 0, "    ", ( F ) )
314
	print_source((L), 1, 0, "    ",(F))
249
 
315
 
250
#define PRINT_FROM( L, F )\
316
#define PRINT_FROM(L, F)\
251
	fputs_v ( "    (included from ", ( F ) ) ;\
317
	fputs_v("    (included from ",(F));\
252
	print_location ( ( L ), ( F ) ) ;\
318
	print_location((L), (F));\
253
	fputs_v ( ")\n", ( F ) )
319
	fputs_v(")\n",(F))
254
 
320
 
255
#define PRINT_START( M, F )\
321
#define PRINT_START(M, F)\
256
	fputs_v ( ( M ), ( F ) ) ;\
322
	fputs_v((M), (F));\
257
	fputs_v ( ": ", ( F ) )
323
	fputs_v(": ",(F))
258
 
324
 
259
#define MESSAGE_START		"  "
325
#define MESSAGE_START		"  "
260
#define MESSAGE_END		".\n"
326
#define MESSAGE_END		".\n"
261
#define MESSAGE_TERM		"\n"
327
#define MESSAGE_TERM		"\n"
262
#define MESSAGE_NAME		"[%x]: "
328
#define MESSAGE_NAME		"[%x]: "
263
#define MESSAGE_ISO		"[ISO %x]: "
329
#define MESSAGE_ISO		"[ISO %x]: "
Line 273... Line 339...
273
    FORWARD DECLARATION
339
    FORWARD DECLARATION
274
 
340
 
275
    The following forward declaration is necessary.
341
    The following forward declaration is necessary.
276
*/
342
*/
277
 
343
 
278
static void print_error_msg PROTO_S ( ( ERROR, LOCATION *, FILE * ) ) ;
344
static void print_error_msg(ERROR, LOCATION *, FILE *);
279
 
345
 
280
 
346
 
281
/*
347
/*
282
    TERMINATE PROGRAM
348
    TERMINATE PROGRAM
283
 
349
 
Line 286... Line 352...
286
    a memory allocation error when the amount of tidying up which can
352
    a memory allocation error when the amount of tidying up which can
287
    be done is limited, although some memory is freed to give a little
353
    be done is limited, although some memory is freed to give a little
288
    leeway.
354
    leeway.
289
*/
355
*/
290
 
356
 
291
void term_error
357
void
292
    PROTO_N ( ( fatal ) )
-
 
293
    PROTO_T ( int fatal )
358
term_error(int fatal)
294
{
359
{
295
    if ( fatal ) {
360
	if (fatal) {
296
	/* Cope with memory allocation errors */
361
		/* Cope with memory allocation errors */
297
	exit_status = EXIT_FAILURE ;
362
		exit_status = EXIT_FAILURE;
298
	output_capsule = 0 ;
363
		output_capsule = 0;
299
	output_spec = 0 ;
364
		output_spec = 0;
300
	free_buffer ( &token_buff ) ;
365
		free_buffer(&token_buff);
301
    }
366
	}
302
    if ( do_dump ) {
367
	if (do_dump) {
303
	/* End dump file */
368
		/* End dump file */
304
	term_dump () ;
369
		term_dump();
305
	do_dump = 0 ;
370
		do_dump = 0;
306
    }
371
	}
307
    if ( do_error ) {
372
	if (do_error) {
308
	/* Report errors in dump file */
373
		/* Report errors in dump file */
309
	unsigned long e = number_errors ;
374
		unsigned long e = number_errors;
310
	unsigned long w = number_warnings ;
375
		unsigned long w = number_warnings;
311
	int sev = ( e ? ERROR_SERIOUS : ERROR_WARNING ) ;
376
		int sev = (e ? ERROR_SERIOUS : ERROR_WARNING);
312
	do_error = 0 ;
377
		do_error = 0;
313
	error ( sev, "%lu error(s), %lu warning(s)", e, w ) ;
378
		error(sev, "%lu error(s), %lu warning(s)", e, w);
314
    }
379
	}
315
    if ( output_name [ OUTPUT_SPEC ] ) {
380
	if (output_name[OUTPUT_SPEC]) {
316
	/* Write spec file */
381
		/* Write spec file */
317
	begin_spec () ;
382
		begin_spec();
318
	end_spec () ;
383
		end_spec();
319
    }
384
	}
320
    if ( output_tdf ) {
385
	if (output_tdf) {
321
	/* Write capsule */
386
		/* Write capsule */
322
	write_capsule () ;
387
		write_capsule();
323
    }
388
	}
324
    exit ( exit_status ) ;
389
	exit(exit_status);
325
}
390
}
326
 
391
 
327
 
392
 
328
/*
393
/*
329
    ERROR BREAKPOINT ROUTINE
394
    ERROR BREAKPOINT ROUTINE
330
 
395
 
331
    This routine is intended to aid in debugging.  It is called just after
396
    This routine is intended to aid in debugging.  It is called just after
332
    any error message is printed.
397
    any error message is printed.
333
*/
398
*/
334
 
399
 
335
static void error_break
400
static void
336
    PROTO_Z ()
401
error_break(void)
337
{
402
{
338
    return ;
403
	return;
339
}
404
}
340
 
405
 
341
 
406
 
342
/*
407
/*
343
    FIND AN ERROR MESSAGE HEADER
408
    FIND AN ERROR MESSAGE HEADER
344
 
409
 
345
    This routine returns the error message header for an error of severity
410
    This routine returns the error message header for an error of severity
346
    sev.  It also updates the internal flags.
411
    sev.  It also updates the internal flags.
347
*/
412
*/
348
 
413
 
349
static CONST char *error_header
414
static CONST char *
350
    PROTO_N ( ( sev ) )
-
 
351
    PROTO_T ( int sev )
415
error_header(int sev)
352
{
416
{
353
    CONST char *msg ;
417
	CONST char *msg;
354
    switch ( sev ) {
418
	switch (sev) {
355
	case ERROR_FATAL : {
419
	case ERROR_FATAL: {
356
	    msg = HEADER_FATAL ;
420
		msg = HEADER_FATAL;
357
	    exit_status = EXIT_FAILURE ;
-
 
358
	    output_capsule = 0 ;
-
 
359
	    number_errors++ ;
-
 
360
	    break ;
-
 
361
	}
-
 
362
	case ERROR_INTERNAL : {
-
 
363
	    msg = HEADER_INTERNAL ;
-
 
364
	    if ( error_severity [ OPTION_ON ] == ERROR_SERIOUS ) {
-
 
365
		exit_status = EXIT_FAILURE ;
421
		exit_status = EXIT_FAILURE;
366
		output_capsule = 0 ;
422
		output_capsule = 0;
367
	    }
-
 
368
	    number_errors++ ;
423
		number_errors++;
369
	    break ;
424
		break;
370
	}
425
	}
371
	default : {
426
	case ERROR_INTERNAL: {
372
	    msg = HEADER_SERIOUS ;
427
		msg = HEADER_INTERNAL;
373
	    if ( error_severity [ OPTION_ON ] == ERROR_SERIOUS ) {
428
		if (error_severity[OPTION_ON] == ERROR_SERIOUS) {
374
		exit_status = EXIT_FAILURE ;
429
			exit_status = EXIT_FAILURE;
375
		output_capsule = 0 ;
430
			output_capsule = 0;
376
	    }
431
		}
377
	    number_errors++ ;
432
		number_errors++;
378
	    break ;
433
		break;
379
	}
434
	}
-
 
435
	default : {
-
 
436
		msg = HEADER_SERIOUS;
-
 
437
		if (error_severity[OPTION_ON] == ERROR_SERIOUS) {
-
 
438
			exit_status = EXIT_FAILURE;
-
 
439
			output_capsule = 0;
-
 
440
		}
-
 
441
		number_errors++;
-
 
442
		break;
-
 
443
	}
380
	case ERROR_WARNING : {
444
	case ERROR_WARNING: {
381
	    msg = HEADER_WARNING ;
445
		msg = HEADER_WARNING;
382
	    number_warnings++ ;
446
		number_warnings++;
383
	    break ;
447
		break;
384
	}
448
	}
385
    }
449
	}
386
    return ( msg ) ;
450
	return (msg);
387
}
451
}
388
 
452
 
389
 
453
 
390
/*
454
/*
391
    PRINT A LOCATION TO A FILE
455
    PRINT A LOCATION TO A FILE
392
 
456
 
393
    This routine prints the location loc to the file f.
457
    This routine prints the location loc to the file f.
394
*/
458
*/
395
 
459
 
396
static void print_location
460
static void
397
    PROTO_N ( ( loc, f ) )
-
 
398
    PROTO_T ( LOCATION *loc X FILE *f )
461
print_location(LOCATION *loc, FILE *f)
399
{
462
{
400
    BUFFER *bf = clear_buffer ( &print_buff, f ) ;
463
	BUFFER *bf = clear_buffer(&print_buff, f);
401
    IGNORE print_loc ( loc, NIL ( LOCATION ), bf, 0 ) ;
464
	IGNORE print_loc(loc, NIL(LOCATION), bf, 0);
402
    output_buffer ( bf, 0 ) ;
465
	output_buffer(bf, 0);
403
    return ;
466
	return;
404
}
467
}
405
 
468
 
406
 
469
 
407
/*
470
/*
408
    CONVERT AN ISO SECTION NUMBER TO AN ANSI SECTION NUMBER
471
    CONVERT AN ISO SECTION NUMBER TO AN ANSI SECTION NUMBER
409
 
472
 
410
    The ISO C standard was based on the ANSI C standard but the sections
473
    The ISO C standard was based on the ANSI C standard but the sections
411
    were renumbered.  The ISO and ANSI C++ standards are identical.  This
474
    were renumbered.  The ISO and ANSI C++ standards are identical.  This
412
    routine converts the ISO section number s to the corresponding ANSI
475
    routine converts the ISO section number s to the corresponding ANSI
413
    section number, printing it to the buffer bf.
476
    section number, printing it to the buffer bf.
414
*/
477
*/
415
 
478
 
416
static void iso_to_ansi
479
static void
417
    PROTO_N ( ( bf, s ) )
-
 
418
    PROTO_T ( BUFFER *bf X CONST char *s )
480
iso_to_ansi(BUFFER *bf, CONST char *s)
419
{
481
{
420
#if LANGUAGE_C
482
#if LANGUAGE_C
421
    char c ;
483
	char c;
422
    unsigned long n = 0 ;
484
	unsigned long n = 0;
423
    CONST char *p = "1." ;
485
	CONST char *p = "1.";
424
    CONST char *q = s ;
486
	CONST char *q = s;
425
    while ( c = *q, ( c >= '0' && c <= '9' ) ) {
487
	while (c = *q,(c >= '0' && c <= '9')) {
426
	n = 10 * n + ( unsigned long ) ( c - '0' ) ;
488
		n = 10 * n + (unsigned long)(c - '0');
427
	q++ ;
489
		q++;
428
    }
490
	}
429
    if ( n == 0 ) {
491
	if (n == 0) {
430
	bfprintf ( bf, "%x", s ) ;
492
		bfprintf(bf, "%x", s);
431
    } else {
493
	} else {
432
	switch ( n ) {
494
		switch (n) {
433
	    case 1 : n = 2 ; break ;
495
		case 1:
-
 
496
			n = 2;
-
 
497
			break;
434
	    case 2 : n = 3 ; break ;
498
		case 2:
-
 
499
			n = 3;
-
 
500
			break;
435
	    case 3 : n = 6 ; break ;
501
		case 3:
-
 
502
			n = 6;
-
 
503
			break;
436
	    case 4 : n = 7 ; break ;
504
		case 4:
-
 
505
			n = 7;
-
 
506
			break;
-
 
507
		default:
-
 
508
			p = "";
-
 
509
			n -= 3;
-
 
510
			break;
-
 
511
		}
437
	    default : p = "" ; n -= 3 ; break ;
512
		bfprintf(bf, "%x%lu%x", p, n, q);
438
	}
513
	}
439
	bfprintf ( bf, "%x%lu%x", p, n, q ) ;
-
 
440
    }
-
 
441
#else
514
#else
442
    bfprintf ( bf, "%x", s ) ;
515
	bfprintf(bf, "%x", s);
443
#endif
516
#endif
444
    return ;
517
	return;
445
}
518
}
446
 
519
 
447
 
520
 
448
/*
521
/*
449
    PRINT THE START OF AN ERROR MESSAGE
522
    PRINT THE START OF AN ERROR MESSAGE
450
 
523
 
451
    This routine prints the start of an error message of severity sev and
524
    This routine prints the start of an error message of severity sev and
452
    location loc to the file f.
525
    location loc to the file f.
453
*/
526
*/
454
 
527
 
455
static void print_error_start
528
static void
456
    PROTO_N ( ( f, loc, sev ) )
-
 
457
    PROTO_T ( FILE *f X LOCATION *loc X int sev )
529
print_error_start(FILE *f, LOCATION *loc, int sev)
458
{
530
{
459
    CONST char *msg = error_header ( sev ) ;
531
	CONST char *msg = error_header(sev);
460
    if ( loc ) {
532
	if (loc) {
461
	PRINT_HEADER ( msg, loc, f ) ;
533
		PRINT_HEADER(msg, loc, f);
462
	if ( print_error_loc ) {
534
		if (print_error_loc) {
463
	    /* Print full error location */
535
			/* Print full error location */
464
	    LOCATION floc ;
536
			LOCATION floc;
465
	    LOCATION *ploc = loc ;
537
			LOCATION *ploc = loc;
466
	    for ( ; ; ) {
538
			for (;;) {
467
		PTR ( LOCATION ) from ;
539
				PTR(LOCATION)from;
468
		PTR ( POSITION ) posn = ploc->posn ;
540
				PTR(POSITION)posn = ploc->posn;
469
		if ( IS_NULL_ptr ( posn ) ) break ;
541
				if (IS_NULL_ptr(posn)) {
-
 
542
					break;
-
 
543
				}
470
		from = DEREF_ptr ( posn_from ( posn ) ) ;
544
				from = DEREF_ptr(posn_from(posn));
471
		if ( IS_NULL_ptr ( from ) ) break ;
545
				if (IS_NULL_ptr(from)) {
-
 
546
					break;
-
 
547
				}
472
		DEREF_loc ( from, floc ) ;
548
				DEREF_loc(from, floc);
473
		ploc = &floc ;
549
				ploc = &floc;
474
		PRINT_FROM ( ploc, f ) ;
550
				PRINT_FROM(ploc, f);
475
	    }
551
			}
476
	}
552
		}
477
	if ( print_error_source ) {
553
		if (print_error_source) {
478
	    /* Print source line */
554
			/* Print source line */
479
	    PRINT_SOURCE ( loc, f ) ;
555
			PRINT_SOURCE(loc, f);
-
 
556
		}
-
 
557
	} else {
-
 
558
		PRINT_START(msg, f);
480
	}
559
	}
481
    } else {
-
 
482
	PRINT_START ( msg, f ) ;
-
 
483
    }
-
 
484
    return ;
560
	return;
485
}
561
}
486
 
562
 
487
 
563
 
488
/*
564
/*
489
    PRINT THE END OF AN ERROR MESSAGE
565
    PRINT THE END OF AN ERROR MESSAGE
490
 
566
 
491
    This routine prints the end of an error message of severity sev to
567
    This routine prints the end of an error message of severity sev to
492
    the file f.
568
    the file f.
493
*/
569
*/
494
 
570
 
495
static void print_error_end
571
static void
496
    PROTO_N ( ( f, sev ) )
-
 
497
    PROTO_T ( FILE *f X int sev )
572
print_error_end(FILE *f, int sev)
498
{
573
{
499
    unsigned long n = number_errors ;
574
	unsigned long n = number_errors;
500
    if ( n >= max_errors && sev != ERROR_FATAL ) {
575
	if (n >= max_errors && sev != ERROR_FATAL) {
501
	ERROR err = ERR_fail_too_many ( n ) ;
576
		ERROR err = ERR_fail_too_many(n);
502
	print_error_msg ( err, &crt_loc, f ) ;
577
		print_error_msg(err, &crt_loc, f);
503
	sev = ERROR_FATAL ;
578
		sev = ERROR_FATAL;
504
    }
579
	}
505
    fputs_v ( MESSAGE_TERM, f ) ;
580
	fputs_v(MESSAGE_TERM, f);
506
    error_break () ;
581
	error_break();
507
    if ( sev == ERROR_FATAL ) term_error ( 0 ) ;
582
	if (sev == ERROR_FATAL) {
-
 
583
		term_error(0);
-
 
584
	}
508
    return ;
585
	return;
509
}
586
}
510
 
587
 
511
 
588
 
512
/*
589
/*
513
    OPTION SEVERITY LEVELS
590
    OPTION SEVERITY LEVELS
514
 
591
 
515
    This table gives the mapping between options and error severity
592
    This table gives the mapping between options and error severity
516
    levels.
593
    levels.
517
*/
594
*/
518
 
595
 
519
int error_severity [] = {
596
int error_severity[] = {
520
    ERROR_NONE,				/* OPTION_OFF */
597
	ERROR_NONE,			/* OPTION_OFF */
521
    ERROR_WARNING,			/* OPTION_WARN */
598
	ERROR_WARNING,			/* OPTION_WARN */
522
    ERROR_SERIOUS,			/* OPTION_ON */
599
	ERROR_SERIOUS,			/* OPTION_ON */
523
    ERROR_WHATEVER			/* OPTION_WHATEVER */
600
	ERROR_WHATEVER			/* OPTION_WHATEVER */
524
} ;
601
};
525
 
602
 
526
int default_severity [] = {
603
int default_severity[] = {
527
    ERROR_NONE,				/* OPTION_OFF */
604
	ERROR_NONE,			/* OPTION_OFF */
528
    ERROR_WARNING,			/* OPTION_WARN */
605
	ERROR_WARNING,			/* OPTION_WARN */
529
    ERROR_SERIOUS,			/* OPTION_ON */
606
	ERROR_SERIOUS,			/* OPTION_ON */
530
    ERROR_WHATEVER			/* OPTION_WHATEVER */
607
	ERROR_WHATEVER			/* OPTION_WHATEVER */
531
} ;
608
};
532
 
609
 
533
 
610
 
534
/*
611
/*
535
    CREATE AN ERROR STRUCTURE
612
    CREATE AN ERROR STRUCTURE
536
 
613
 
537
    This routine creates a structure for error n in the error catalogue.
614
    This routine creates a structure for error n in the error catalogue.
538
    Any extra arguments needed by the error should also be given.  Because
615
    Any extra arguments needed by the error should also be given.  Because
539
    of restrictions imposed by the way that stdarg is implemented, any
616
    of restrictions imposed by the way that stdarg is implemented, any
540
    structure arguments need to be explicitly passed by reference.  Note
617
    structure arguments need to be explicitly passed by reference.  Note
541
    that these arguments are stored in the result in reverse order.
618
    that these arguments are stored in the result in reverse order.
542
*/
619
*/
543
 
620
 
544
ERROR make_error
621
ERROR
545
    PROTO_V ( ( int n, ... ) ) /* VARARGS */
622
make_error(int n, ...) /* VARARGS */
546
{
623
{
547
    int sev ;
624
	int sev;
548
    ERROR e ;
625
	ERROR e;
549
    OPTION opt ;
626
	OPTION opt;
550
    va_list args ;
627
	va_list args;
551
    ERR_DATA *msg ;
628
	ERR_DATA *msg;
552
    CONST char *s ;
629
	CONST char *s;
553
#if FS_STDARG
630
#if FS_STDARG
554
    va_start ( args, n ) ;
631
	va_start(args, n);
555
#else
632
#else
556
    int n ;
633
	int n;
557
    va_start ( args ) ;
634
	va_start(args);
558
    n = va_arg ( args, int ) ;
635
	n = va_arg(args, int);
559
#endif
636
#endif
560
 
637
 
693
		}
772
		}
694
	    }
-
 
695
	}
773
	}
696
    }
-
 
697
    va_end ( args ) ;
774
	va_end(args);
698
    return ( e ) ;
775
	return (e);
699
}
776
}
700
 
777
 
701
 
778
 
702
/*
779
/*
703
    PRINT THE BODY OF AN ERROR STRUCTURE
780
    PRINT THE BODY OF AN ERROR STRUCTURE
704
 
781
 
705
    This routine prints the body of the simple error message e to the
782
    This routine prints the body of the simple error message e to the
706
    buffer bf.
783
    buffer bf.
707
*/
784
*/
708
 
785
 
709
static void print_error_body
786
static void
710
    PROTO_N ( ( e, loc, bf ) )
-
 
711
    PROTO_T ( ERROR e X LOCATION *loc X BUFFER *bf )
787
print_error_body(ERROR e, LOCATION *loc, BUFFER *bf)
712
{
788
{
713
    char c ;
789
	char c;
714
    QUALIFIER qual = qual_none ;
790
	QUALIFIER qual = qual_none;
715
 
791
 
716
    /* Extract error information */
792
	/* Extract error information */
717
    int n = DEREF_int ( err_simple_number ( e ) ) ;
793
	int n = DEREF_int(err_simple_number(e));
718
    unsigned sz = DEREF_unsigned ( err_simple_size ( e ) ) ;
794
	unsigned sz = DEREF_unsigned(err_simple_size(e));
719
 
795
 
720
    /* Look up error in catalogue */
796
	/* Look up error in catalogue */
721
    ERR_DATA *msg = ERR_CATALOG + n ;
797
	ERR_DATA *msg = ERR_CATALOG + n;
722
    CONST char *sig = msg->signature ;
798
	CONST char *sig = msg->signature;
723
    CONST char *s = msg->key_STD ;
799
	CONST char *s = msg->key_STD;
724
 
800
 
890
		}
983
		}
891
		case ERR_KEY_unsigned : {
-
 
892
		    unsigned arg ;
-
 
893
		    arg = DEREF_unsigned ( err_arg ( e, a, unsigned ) ) ;
-
 
894
		    bfprintf ( bf, "%u", arg ) ;
-
 
895
		    break ;
-
 
896
		}
-
 
897
		default : {
-
 
898
		    bfprintf ( bf, "<arg%u>", a ) ;
-
 
899
		    break ;
-
 
900
		}
-
 
901
	    }
-
 
902
	} else {
-
 
903
	    /* Other characters */
-
 
904
	    bfputc ( bf, c ) ;
-
 
905
	}
984
	}
906
    }
-
 
907
    return ;
985
	return;
908
}
986
}
909
 
987
 
910
 
988
 
911
/*
989
/*
912
    PRINT AN ERROR STRUCTURE
990
    PRINT AN ERROR STRUCTURE
913
 
991
 
914
    This routine prints the body of the error message given by e to the
992
    This routine prints the body of the error message given by e to the
915
    file f.
993
    file f.
916
*/
994
*/
917
 
995
 
918
static void print_error_msg
996
static void
919
    PROTO_N ( ( e, loc, f ) )
-
 
920
    PROTO_T ( ERROR e X LOCATION *loc X FILE *f )
997
print_error_msg(ERROR e, LOCATION *loc, FILE *f)
921
{
998
{
922
    if ( IS_err_simple ( e ) ) {
999
	if (IS_err_simple(e)) {
923
	/* Print simple error message */
1000
		/* Print simple error message */
924
	BUFFER *bf ;
1001
		BUFFER *bf;
925
	int n = DEREF_int ( err_simple_number ( e ) ) ;
1002
		int n = DEREF_int(err_simple_number(e));
926
	ERR_DATA *msg = ERR_CATALOG + n ;
1003
		ERR_DATA *msg = ERR_CATALOG + n;
927
	ERR_PROPS props = msg->props ;
1004
		ERR_PROPS props = msg->props;
928
	int sev = DEREF_int ( err_severity ( e ) ) ;
1005
		int sev = DEREF_int(err_severity(e));
929
	if ( sev == ERROR_WHATEVER && print_short ) return ;
1006
		if (sev == ERROR_WHATEVER && print_short) return;
930
	bf = clear_buffer ( &print_buff, f ) ;
1007
		bf = clear_buffer(&print_buff, f);
931
	if ( loc ) bfprintf ( bf, MESSAGE_START ) ;
1008
		if (loc)bfprintf(bf, MESSAGE_START);
932
	if ( print_error_name ) {
1009
		if (print_error_name) {
933
	    CONST char *name = msg->name ;
1010
			CONST char *name = msg->name;
934
	    if ( name ) bfprintf ( bf, MESSAGE_NAME, name ) ;
1011
			if (name)bfprintf(bf, MESSAGE_NAME, name);
935
	}
-
 
936
	if ( !( props & ERR_PROP_non_iso ) && print_iso_ref ) {
-
 
937
	    CONST char *iso ;
-
 
938
	    ERR_DATA *prev = msg ;
-
 
939
	    while ( iso = prev->key_ISO, iso == NULL ) {
-
 
940
		/* Scan back to current section number */
-
 
941
		if ( prev == ERR_CATALOG ) break ;
-
 
942
		prev-- ;
-
 
943
	    }
-
 
944
	    msg->key_ISO = iso ;
-
 
945
	    if ( iso && iso [0] ) {
-
 
946
		if ( print_ansi_ref ) {
-
 
947
		    bfprintf ( bf, MESSAGE_ANSI ) ;
-
 
948
		    iso_to_ansi ( bf, iso ) ;
-
 
949
		    bfprintf ( bf, MESSAGE_ANSI_END ) ;
-
 
950
		} else {
-
 
951
		    bfprintf ( bf, MESSAGE_ISO, iso ) ;
-
 
952
		}
1012
		}
-
 
1013
		if (!(props & ERR_PROP_non_iso) && print_iso_ref) {
-
 
1014
			CONST char *iso;
-
 
1015
			ERR_DATA *prev = msg;
-
 
1016
			while (iso = prev->key_ISO, iso == NULL) {
-
 
1017
				/* Scan back to current section number */
-
 
1018
				if (prev == ERR_CATALOG)break;
-
 
1019
				prev--;
-
 
1020
			}
-
 
1021
			msg->key_ISO = iso;
-
 
1022
			if (iso && iso[0]) {
-
 
1023
				if (print_ansi_ref) {
-
 
1024
					bfprintf(bf, MESSAGE_ANSI);
-
 
1025
					iso_to_ansi(bf, iso);
-
 
1026
					bfprintf(bf, MESSAGE_ANSI_END);
-
 
1027
				} else {
-
 
1028
					bfprintf(bf, MESSAGE_ISO, iso);
953
	    }
1029
				}
-
 
1030
			}
954
	}
1031
		}
955
	if ( props ) {
1032
		if (props) {
-
 
1033
			if (props & ERR_PROP_pragma) {
-
 
1034
				bfprintf(bf, MESSAGE_PRAGMA);
-
 
1035
			}
956
	    if ( props & ERR_PROP_pragma ) bfprintf ( bf, MESSAGE_PRAGMA ) ;
1036
			if (props & ERR_PROP_printf) {
957
	    if ( props & ERR_PROP_printf ) bfprintf ( bf, MESSAGE_PRINTF ) ;
1037
				bfprintf(bf, MESSAGE_PRINTF);
-
 
1038
			}
-
 
1039
			if (props & ERR_PROP_token) {
958
	    if ( props & ERR_PROP_token ) bfprintf ( bf, MESSAGE_TOKEN ) ;
1040
				bfprintf(bf, MESSAGE_TOKEN);
-
 
1041
			}
-
 
1042
			if (props & ERR_PROP_syntax) {
959
	    if ( props & ERR_PROP_syntax ) bfprintf ( bf, MESSAGE_SYNTAX ) ;
1043
				bfprintf(bf, MESSAGE_SYNTAX);
-
 
1044
			}
960
	}
1045
		}
961
	print_error_body ( e, loc, bf ) ;
1046
		print_error_body(e, loc, bf);
962
	bfprintf ( bf, MESSAGE_END ) ;
1047
		bfprintf(bf, MESSAGE_END);
963
	output_buffer ( bf, 1 ) ;
1048
		output_buffer(bf, 1);
964
 
1049
 
965
    } else {
1050
	} else {
966
	/* Print composite error message */
1051
		/* Print composite error message */
967
	ERROR e1 = DEREF_err ( err_compound_head ( e ) ) ;
1052
		ERROR e1 = DEREF_err(err_compound_head(e));
968
	ERROR e2 = DEREF_err ( err_compound_tail ( e ) ) ;
1053
		ERROR e2 = DEREF_err(err_compound_tail(e));
969
	print_error_msg ( e1, loc, f ) ;
1054
		print_error_msg(e1, loc, f);
970
	print_error_msg ( e2, loc, f ) ;
1055
		print_error_msg(e2, loc, f);
971
    }
1056
	}
972
    return ;
1057
	return;
973
}
1058
}
974
 
1059
 
975
 
1060
 
976
/*
1061
/*
977
    DESTROY AN ERROR STRUCTURE
1062
    DESTROY AN ERROR STRUCTURE
978
 
1063
 
979
    This routine destroys the error structure e.  If d is false then the
1064
    This routine destroys the error structure e.  If d is false then the
980
    first component of a compound error is not destroyed.
1065
    first component of a compound error is not destroyed.
981
*/
1066
*/
982
 
1067
 
983
void destroy_error
1068
void
984
    PROTO_N ( ( e, d ) )
-
 
985
    PROTO_T ( ERROR e X int d )
1069
destroy_error(ERROR e, int d)
986
{
1070
{
987
    if ( !IS_NULL_err ( e ) ) {
1071
	if (!IS_NULL_err(e)) {
988
	if ( IS_err_simple ( e ) ) {
1072
		if (IS_err_simple(e)) {
989
	    if ( d ) DESTROY_err_simple_args ( e ) ;
1073
			if (d)DESTROY_err_simple_args(e);
990
	} else {
1074
		} else {
991
	    int sev ;
1075
			int sev;
992
	    ERROR e1, e2 ;
1076
			ERROR e1, e2;
993
	    DESTROY_err_compound ( destroy, sev, e1, e2, e ) ;
1077
			DESTROY_err_compound(destroy, sev, e1, e2, e);
994
	    if ( d ) destroy_error ( e1, 1 ) ;
1078
			if (d)destroy_error(e1, 1);
995
	    destroy_error ( e2, 1 ) ;
1079
			destroy_error(e2, 1);
996
	    UNUSED ( sev ) ;
1080
			UNUSED(sev);
-
 
1081
		}
997
	}
1082
	}
998
    }
-
 
999
    return ;
1083
	return;
1000
}
1084
}
1001
 
1085
 
1002
 
1086
 
1003
/*
1087
/*
1004
    JOIN TWO ERROR STRUCTURES
1088
    JOIN TWO ERROR STRUCTURES
1005
 
1089
 
1006
    This routine joins the error structures e1 and e2 into a single compound
1090
    This routine joins the error structures e1 and e2 into a single compound
1007
    error structure.
1091
    error structure.
1008
*/
1092
*/
1009
 
1093
 
1010
ERROR concat_error
1094
ERROR
1011
    PROTO_N ( ( e1, e2 ) )
-
 
1012
    PROTO_T ( ERROR e1 X ERROR e2 )
1095
concat_error(ERROR e1, ERROR e2)
1013
{
1096
{
1014
    ERROR e ;
1097
	ERROR e;
1015
    int s1, s2 ;
1098
	int s1, s2;
1016
    if ( IS_NULL_err ( e1 ) ) return ( e2 ) ;
1099
	if (IS_NULL_err(e1)) {
-
 
1100
		return (e2);
-
 
1101
	}
1017
    if ( IS_NULL_err ( e2 ) ) return ( e1 ) ;
1102
	if (IS_NULL_err(e2)) {
-
 
1103
		return (e1);
-
 
1104
	}
1018
    s1 = DEREF_int ( err_severity ( e1 ) ) ;
1105
	s1 = DEREF_int(err_severity(e1));
1019
    s2 = DEREF_int ( err_severity ( e2 ) ) ;
1106
	s2 = DEREF_int(err_severity(e2));
1020
    if ( s2 > s1 ) s1 = s2 ;
1107
	if (s2 > s1) {
-
 
1108
		s1 = s2;
-
 
1109
	}
1021
    MAKE_err_compound ( s1, e1, e2, e ) ;
1110
	MAKE_err_compound(s1, e1, e2, e);
1022
    return ( e ) ;
1111
	return (e);
1023
}
1112
}
1024
 
1113
 
1025
 
1114
 
1026
/*
1115
/*
1027
    OPTIONALLY JOIN TWO ERROR STRUCTURES
1116
    OPTIONALLY JOIN TWO ERROR STRUCTURES
1028
 
1117
 
1029
    This routine joins the error structures e1 and e2 into a single compound
1118
    This routine joins the error structures e1 and e2 into a single compound
1030
    error structure if e1 represents a serious error.  Otherwise e2 is
1119
    error structure if e1 represents a serious error.  Otherwise e2 is
1031
    destroyed and e1 is returned.
1120
    destroyed and e1 is returned.
1032
*/
1121
*/
1033
 
1122
 
1034
ERROR concat_warning
1123
ERROR
1035
    PROTO_N ( ( e1, e2 ) )
-
 
1036
    PROTO_T ( ERROR e1 X ERROR e2 )
1124
concat_warning(ERROR e1, ERROR e2)
1037
{
1125
{
1038
    ERROR e ;
1126
	ERROR e;
1039
    int s1, s2 ;
1127
	int s1, s2;
1040
    if ( IS_NULL_err ( e1 ) ) return ( e2 ) ;
1128
	if (IS_NULL_err(e1)) {
-
 
1129
		return (e2);
-
 
1130
	}
1041
    if ( IS_NULL_err ( e2 ) ) return ( e1 ) ;
1131
	if (IS_NULL_err(e2)) {
-
 
1132
		return (e1);
-
 
1133
	}
1042
    s1 = DEREF_int ( err_severity ( e1 ) ) ;
1134
	s1 = DEREF_int(err_severity(e1));
1043
    if ( s1 > ERROR_WARNING ) {
1135
	if (s1 > ERROR_WARNING) {
1044
	s2 = DEREF_int ( err_severity ( e2 ) ) ;
1136
		s2 = DEREF_int(err_severity(e2));
1045
	if ( s2 > s1 ) s1 = s2 ;
1137
		if (s2 > s1) {
-
 
1138
			s1 = s2;
-
 
1139
		}
1046
	MAKE_err_compound ( s1, e1, e2, e ) ;
1140
		MAKE_err_compound(s1, e1, e2, e);
1047
    } else {
1141
	} else {
1048
	destroy_error ( e2, 1 ) ;
1142
		destroy_error(e2, 1);
1049
	e = e1 ;
1143
		e = e1;
1050
    }
1144
	}
1051
    return ( e ) ;
1145
	return (e);
1052
}
1146
}
1053
 
1147
 
1054
 
1148
 
1055
/*
1149
/*
1056
    ADD AN ERROR TO A LIST
1150
    ADD AN ERROR TO A LIST
1057
 
1151
 
1058
    This routine adds the error e to the end of the list indicated by err.
1152
    This routine adds the error e to the end of the list indicated by err.
1059
    If err is the null pointer then e is destroyed.
1153
    If err is the null pointer then e is destroyed.
1060
*/
1154
*/
1061
 
1155
 
1062
void add_error
1156
void
1063
    PROTO_N ( ( err, e ) )
-
 
1064
    PROTO_T ( ERROR *err X ERROR e )
1157
add_error(ERROR *err, ERROR e)
1065
{
1158
{
1066
    if ( !IS_NULL_err ( e ) ) {
1159
	if (!IS_NULL_err(e)) {
1067
	if ( err ) {
1160
		if (err) {
1068
	    ERROR e1 = *err ;
1161
			ERROR e1 = *err;
1069
	    if ( IS_NULL_err ( e1 ) ) {
1162
			if (IS_NULL_err(e1)) {
1070
		*err = e ;
1163
				*err = e;
1071
	    } else {
1164
			} else {
1072
		int s1 = DEREF_int ( err_severity ( e1 ) ) ;
1165
				int s1 = DEREF_int(err_severity(e1));
1073
		int s2 = DEREF_int ( err_severity ( e ) ) ;
1166
				int s2 = DEREF_int(err_severity(e));
1074
		if ( s2 > s1 ) s1 = s2 ;
1167
				if (s2 > s1) {
-
 
1168
					s1 = s2;
-
 
1169
				}
1075
		MAKE_err_compound ( s1, e1, e, *err ) ;
1170
				MAKE_err_compound(s1, e1, e, *err);
1076
	    }
1171
			}
1077
	} else {
1172
		} else {
1078
	    destroy_error ( e, 1 ) ;
1173
			destroy_error(e, 1);
-
 
1174
		}
1079
	}
1175
	}
1080
    }
-
 
1081
    return ;
1176
	return;
1082
}
1177
}
1083
 
1178
 
1084
 
1179
 
1085
/*
1180
/*
1086
    STANDARD ERROR PREFIX
1181
    STANDARD ERROR PREFIX
1087
 
1182
 
1088
    These variables give an error message which is added to the start
1183
    These variables give an error message which is added to the start
1089
    of any error before it is printed.  The prefix error severity is not
1184
    of any error before it is printed.  The prefix error severity is not
1090
    taken into account in the overall error severity.
1185
    taken into account in the overall error severity.
1091
*/
1186
*/
1092
 
1187
 
1093
static ERROR error_prefix = NULL_err ;
1188
static ERROR error_prefix = NULL_err;
1094
 
1189
 
1095
 
1190
 
1096
/*
1191
/*
1097
    SET ERROR PREFIX
1192
    SET ERROR PREFIX
1098
 
1193
 
1099
    This routine sets the error prefix to be e, returning the previous
1194
    This routine sets the error prefix to be e, returning the previous
1100
    value.
1195
    value.
1101
*/
1196
*/
1102
 
1197
 
1103
ERROR set_prefix
1198
ERROR
1104
    PROTO_N ( ( e ) )
-
 
1105
    PROTO_T ( ERROR e )
1199
set_prefix(ERROR e)
1106
{
1200
{
1107
    ERROR p = error_prefix ;
1201
	ERROR p = error_prefix;
1108
    error_prefix = e ;
1202
	error_prefix = e;
1109
    return ( p ) ;
1203
	return (p);
1110
}
1204
}
1111
 
1205
 
1112
 
1206
 
1113
/*
1207
/*
1114
    RESTORE ERROR PREFIX
1208
    RESTORE ERROR PREFIX
1115
 
1209
 
1116
    This routine restores the error prefix to e, destroying the previous
1210
    This routine restores the error prefix to e, destroying the previous
1117
    value.
1211
    value.
1118
*/
1212
*/
1119
 
1213
 
1120
void restore_prefix
1214
void
1121
    PROTO_N ( ( e ) )
-
 
1122
    PROTO_T ( ERROR e )
1215
restore_prefix(ERROR e)
1123
{
1216
{
1124
    destroy_error ( error_prefix, 1 ) ;
1217
	destroy_error(error_prefix, 1);
1125
    error_prefix = e ;
1218
	error_prefix = e;
1126
    return ;
1219
	return;
1127
}
1220
}
1128
 
1221
 
1129
 
1222
 
1130
/*
1223
/*
1131
    PRINT AN ERROR MESSAGE
1224
    PRINT AN ERROR MESSAGE
1132
 
1225
 
1133
    This routine prints the error e at location loc.
1226
    This routine prints the error e at location loc.
1134
*/
1227
*/
1135
 
1228
 
1136
void print_error
1229
void
1137
    PROTO_N ( ( loc, e ) )
-
 
1138
    PROTO_T ( LOCATION *loc X ERROR e )
1230
print_error(LOCATION *loc, ERROR e)
1139
{
1231
{
1140
    if ( !IS_NULL_err ( e ) ) {
1232
	if (!IS_NULL_err(e)) {
1141
	int d = 1 ;
1233
		int d = 1;
1142
	int sev = DEREF_int ( err_severity ( e ) ) ;
1234
		int sev = DEREF_int(err_severity(e));
1143
	if ( sev > error_threshold ) {
1235
		if (sev > error_threshold) {
1144
	    ERROR p = error_prefix ;
1236
			ERROR p = error_prefix;
1145
	    if ( !IS_NULL_err ( p ) ) {
1237
			if (!IS_NULL_err(p)) {
1146
		/* Add error prefix */
1238
				/* Add error prefix */
1147
		MAKE_err_compound ( sev, p, e, e ) ;
1239
				MAKE_err_compound(sev, p, e, e);
1148
		d = 0 ;
1240
				d = 0;
1149
	    }
1241
			}
1150
	    if ( do_error && dump_error ( e, loc, sev, 0 ) ) {
1242
			if (do_error && dump_error(e, loc, sev, 0)) {
1151
		/* Dump error to file */
1243
				/* Dump error to file */
1152
		unsigned long n ;
1244
				unsigned long n;
1153
		IGNORE error_header ( sev ) ;
1245
				IGNORE error_header(sev);
1154
		n = number_errors ;
1246
				n = number_errors;
1155
		error_break () ;
1247
				error_break();
1156
		if ( sev == ERROR_FATAL ) term_error ( 0 ) ;
1248
				if (sev == ERROR_FATAL)term_error(0);
1157
		if ( n >= max_errors ) term_error ( 0 ) ;
1249
				if (n >= max_errors)term_error(0);
1158
	    } else {
1250
			} else {
1159
		/* Print error to standard error */
1251
				/* Print error to standard error */
1160
		FILE *f = error_file ;
1252
				FILE *f = error_file;
1161
		print_error_start ( f, loc, sev ) ;
1253
				print_error_start(f, loc, sev);
1162
		print_error_msg ( e, loc, f ) ;
1254
				print_error_msg(e, loc, f);
1163
		print_error_end ( f, sev ) ;
1255
				print_error_end(f, sev);
1164
	    }
1256
			}
1165
	}
1257
		}
1166
	destroy_error ( e, d ) ;
1258
		destroy_error(e, d);
1167
    }
1259
	}
1168
    return ;
1260
	return;
1169
}
1261
}
1170
 
1262
 
1171
 
1263
 
1172
/*
1264
/*
1173
    CREATE AN INSTALLER ERROR EXPRESSION
1265
    CREATE AN INSTALLER ERROR EXPRESSION
1174
 
1266
 
1175
    This routine creates an install-time error expression for the error
1267
    This routine creates an install-time error expression for the error
1176
    e at the location loc.
1268
    e at the location loc.
1177
*/
1269
*/
1178
 
1270
 
1179
EXP install_error
1271
EXP
1180
    PROTO_N ( ( loc, e ) )
-
 
1181
    PROTO_T ( LOCATION *loc X ERROR e )
1272
install_error(LOCATION *loc, ERROR e)
1182
{
1273
{
1183
    EXP a = NULL_exp ;
1274
	EXP a = NULL_exp;
1184
    if ( !IS_NULL_err ( e ) ) {
1275
	if (!IS_NULL_err(e)) {
1185
	int sev = DEREF_int ( err_severity ( e ) ) ;
1276
		int sev = DEREF_int(err_severity(e));
1186
	if ( sev > ERROR_WARNING ) {
1277
		if (sev > ERROR_WARNING) {
1187
	    string s ;
1278
			string s;
1188
	    BUFFER *bf = clear_buffer ( &print_buff, NIL ( FILE ) ) ;
1279
			BUFFER *bf = clear_buffer(&print_buff, NIL(FILE));
1189
	    if ( loc ) {
1280
			if (loc) {
1190
		IGNORE print_loc ( loc, NIL ( LOCATION ), bf, 0 ) ;
1281
				IGNORE print_loc(loc, NIL(LOCATION), bf, 0);
1191
		bfprintf ( bf, ": " ) ;
1282
				bfprintf(bf, ": ");
1192
	    }
1283
			}
1193
	    print_error_body ( e, loc, bf ) ;
1284
			print_error_body(e, loc, bf);
1194
	    bfputc ( bf, 0 ) ;
1285
			bfputc(bf, 0);
1195
	    s = xustrcpy ( bf->start ) ;
1286
			s = xustrcpy(bf->start);
1196
	    MAKE_exp_fail ( type_bottom, s, a ) ;
1287
			MAKE_exp_fail(type_bottom, s, a);
1197
	}
1288
		}
1198
	destroy_error ( e, 1 ) ;
1289
		destroy_error(e, 1);
1199
    }
1290
	}
1200
    return ( a ) ;
1291
	return (a);
1201
}
1292
}
1202
 
1293
 
1203
 
1294
 
1204
/*
1295
/*
1205
    PRINT A SIMPLE ERROR
1296
    PRINT A SIMPLE ERROR
1206
 
1297
 
1207
    This routine prints a simple error message at the current location of
1298
    This routine prints a simple error message at the current location of
1208
    severity sev given by the printf style string s.  Any extra arguments
1299
    severity sev given by the printf style string s.  Any extra arguments
1209
    needed by s should also be given.
1300
    needed by s should also be given.
1210
*/
1301
*/
1211
 
1302
 
1212
void error
1303
void
1213
    PROTO_V ( ( int sev, CONST char *s, ... ) ) /* VARARGS */
1304
error(int sev, CONST char *s, ...) /* VARARGS */
1214
{
1305
{
1215
    va_list args ;
1306
	va_list args;
1216
#if FS_STDARG
1307
#if FS_STDARG
1217
    va_start ( args, s ) ;
1308
	va_start(args, s);
1218
#else
1309
#else
1219
    int sev ;
1310
	int sev;
1220
    CONST char *s ;
1311
	CONST char *s;
1221
    va_start ( args ) ;
1312
	va_start(args);
1222
    sev = va_arg ( args, int ) ;
1313
	sev = va_arg(args, int);
1223
    s = va_arg ( args, CONST char * ) ;
1314
	s = va_arg(args, CONST char *);
1224
#endif
1315
#endif
1225
    if ( sev > error_threshold ) {
1316
	if (sev > error_threshold) {
1226
	FILE *f = error_file ;
1317
		FILE *f = error_file;
1227
	print_error_start ( f, NIL ( LOCATION ), sev ) ;
1318
		print_error_start(f, NIL(LOCATION), sev);
1228
	vfprintf_v ( f, s, args ) ;
1319
		vfprintf_v(f, s, args);
1229
	fputs_v ( MESSAGE_END, f ) ;
1320
		fputs_v(MESSAGE_END, f);
1230
	print_error_end ( f, sev ) ;
1321
		print_error_end(f, sev);
1231
    }
1322
	}
1232
    va_end ( args ) ;
1323
	va_end(args);
1233
    return ;
1324
	return;
1234
}
1325
}
1235
 
1326
 
1236
 
1327
 
1237
/*
1328
/*
1238
    PRINT A RUNNING COMMENTARY
1329
    PRINT A RUNNING COMMENTARY
1239
 
1330
 
1240
    This routine is used in verbose mode to print a running commentary of
1331
    This routine is used in verbose mode to print a running commentary of
1241
    the compilation of the object id.
1332
    the compilation of the object id.
1242
*/
1333
*/
1243
 
1334
 
1244
void commentary
1335
void
1245
    PROTO_N ( ( id ) )
-
 
1246
    PROTO_T ( IDENTIFIER id )
1336
commentary(IDENTIFIER id)
1247
{
1337
{
1248
    if ( verbose && !IS_NULL_id ( id ) ) {
1338
	if (verbose && !IS_NULL_id(id)) {
1249
	BUFFER *bf = clear_buffer ( &print_buff, stdout ) ;
1339
		BUFFER *bf = clear_buffer(&print_buff, stdout);
1250
	print_id_desc++ ;
1340
		print_id_desc++;
1251
	IGNORE print_id_long ( id, qual_none, bf, 0 ) ;
1341
		IGNORE print_id_long(id, qual_none, bf, 0);
1252
	print_id_desc-- ;
1342
		print_id_desc--;
1253
	bfprintf ( bf, " ;\n" ) ;
1343
		bfprintf(bf, " ;\n");
1254
	output_buffer ( bf, 1 ) ;
1344
		output_buffer(bf, 1);
1255
    }
1345
	}
1256
    return ;
1346
	return;
1257
}
1347
}
1258
 
1348
 
1259
 
1349
 
1260
/*
1350
/*
1261
    PRINT AN ASSERTION
1351
    PRINT AN ASSERTION
Line 1265... Line 1355...
1265
    check whether the condition of an assertion is false.
1355
    check whether the condition of an assertion is false.
1266
*/
1356
*/
1267
 
1357
 
1268
#ifdef ASSERTS
1358
#ifdef ASSERTS
1269
 
1359
 
1270
void assertion
1360
void
1271
    PROTO_N ( ( s, file, line ) )
-
 
1272
    PROTO_T ( CONST char *s X CONST char *file X int line )
1361
assertion(CONST char *s, CONST char *file, int line)
1273
{
1362
{
1274
    FILE *f = error_file ;
1363
	FILE *f = error_file;
1275
    PRINT_HEADER ( HEADER_ASSERT, &crt_loc, f ) ;
1364
	PRINT_HEADER(HEADER_ASSERT, &crt_loc, f);
1276
    fprintf_v ( f, "  %s, %s: line %d.\n\n", s, file, line ) ;
1365
	fprintf_v(f, "  %s, %s: line %d.\n\n", s, file, line);
1277
    error_break () ;
1366
	error_break();
1278
    abort () ;
1367
	abort();
1279
}
1368
}
1280
 
1369
 
1281
int is_true
1370
int
1282
    PROTO_N ( ( c ) )
-
 
1283
    PROTO_T ( int c )
1371
is_true(int c)
1284
{
1372
{
1285
    return ( c ) ;
1373
	return (c);
1286
}
1374
}
1287
 
1375
 
1288
#endif
1376
#endif