Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 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
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
7 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
7 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
7 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include <limits.h>
63
#if FS_STDARG
64
#include <stdarg.h>
65
#else
66
#include <varargs.h>
67
#endif
68
#include "c_types.h"
69
#include "err_ops.h"
70
#include "exp_ops.h"
71
#include "hashid_ops.h"
72
#include "id_ops.h"
73
#include "str_ops.h"
74
#include "error.h"
75
#include "catalog.h"
76
#include "cast.h"
77
#include "char.h"
78
#include "constant.h"
79
#include "declare.h"
80
#include "file.h"
81
#include "hash.h"
82
#include "instance.h"
83
#include "inttype.h"
84
#include "lex.h"
85
#include "literal.h"
86
#include "namespace.h"
87
#include "option.h"
88
#include "predict.h"
89
#include "preproc.h"
90
#include "redeclare.h"
91
#include "syntax.h"
92
#include "ustring.h"
93
#include "xalloc.h"
94
 
95
 
96
/*
97
    OPTION CATALOGUE
98
 
99
    This table gives the catalogue of all options.  Each entry consists
100
    of an option name plus the default value of the option in the
101
    various standard compilation modes.  The main body is automatically
102
    generated from the error database.
103
*/
104
 
105
#define OPT_VALUE_off		1, { OPTION_OFF, OPTION_OFF }
106
#define OPT_VALUE_on		1, { OPTION_ON, OPTION_ON }
107
#define OPT_VALUE_none		1, { OPTION_ALLOW, OPTION_ALLOW }
108
#define OPT_VALUE_warning	1, { OPTION_WARN, OPTION_WARN }
109
#define OPT_VALUE_error		1, { OPTION_DISALLOW, OPTION_DISALLOW }
110
#define OPT_VALUE_whatever	1, { OPTION_WHATEVER, OPTION_WHATEVER }
111
#define OPT_VALUE_new		1, { OPTION_WARN, OPTION_DISALLOW }
112
#define OPT_VALUE_wall		1, { OPTION_ALLOW, OPTION_WARN }
113
 
7 7u83 114
OPT_DATA OPT_CATALOG[] = {
2 7u83 115
#include "opts.h"
7 7u83 116
	{ NULL, OPT_VALUE_off }
117
};
2 7u83 118
 
7 7u83 119
#define CATALOG_SIZE		array_size(OPT_CATALOG)
2 7u83 120
 
121
 
122
/*
123
    OPTION VALUE CATALOGUE
124
 
125
    This table gives the catalogue of all option values.  Each entry
126
    consists of an option name, its maximum value allowed within the
127
    program, its minimum maximum value allowed by the standard and a
128
    current value.  The entries need to be kept in step with the
129
    OPT_VAL_* macros defined in options.h.  Note that most of the
130
    implementation limits are NO_LIMIT, indicating that there is no
131
    built-in limit.
132
*/
133
 
134
#if LANGUAGE_CPP
7 7u83 135
#define LIMIT(A, B)		((unsigned long)(A))
2 7u83 136
#else
7 7u83 137
#define LIMIT(A, B)		((unsigned long)(B))
2 7u83 138
#endif
139
#define NO_LIMIT		ULONG_MAX
7 7u83 140
#define STR_LIMIT		(ULONG_MAX >> 3)
2 7u83 141
 
7 7u83 142
OPT_VALUE_DATA OPT_VALUE_CATALOG[] = {
143
	/* Implementation quantities (from Annex B) */
144
	{ "statement_depth", &crt_loc, NO_LIMIT, LIMIT(256, 15), 0, 1 },
145
	{ "hash_if_depth", &preproc_loc, NO_LIMIT, LIMIT(256, 8), 0, 1 },
146
	{ "declarator_max", &crt_loc, NO_LIMIT, LIMIT(256, 12), 0, 0 },
147
	{ "paren_depth", &crt_loc, NO_LIMIT, LIMIT(256, 32), 0, 1 },
148
	{ "name_limit", &crt_loc, NO_LIMIT, LIMIT(1024, 31), 0, 0 },
149
	{ "extern_name_limit", &crt_loc, NO_LIMIT, LIMIT(1024, 6), 0, 0 },
150
	{ "external_ids", &crt_loc, NO_LIMIT, LIMIT(65536, 511), 0, 0 },
151
	{ "block_ids", &crt_loc, NO_LIMIT, LIMIT(1024, 127), 0, 0 },
152
	{ "macro_ids", &preproc_loc, NO_LIMIT, LIMIT(65536, 1024), 0, 1 },
153
	{ "func_pars", &crt_loc, NO_LIMIT, LIMIT(256, 31), 0, 0 },
154
	{ "func_args", &crt_loc, NO_LIMIT, LIMIT(256, 31), 0, 0 },
155
	{ "macro_pars", &preproc_loc, NO_LIMIT, LIMIT(256, 31), 0, 0 },
156
	{ "macro_args", &crt_loc, NO_LIMIT, LIMIT(256, 31), 0, 0 },
157
	{ "line_length", &crt_loc, NO_LIMIT, LIMIT(65536, 509), 0, 0 },
158
	{ "string_length", &crt_loc, STR_LIMIT, LIMIT(65536, 509), 0, 0 },
159
	{ "sizeof_object", &crt_loc, NO_LIMIT, LIMIT(262144, 32767), 0, 0 },
160
	{ "include_depth", &preproc_loc, 256, LIMIT(256, 8), 0, 1 },
161
	{ "switch_cases", &crt_loc, NO_LIMIT, LIMIT(16384, 257), 0, 0 },
162
	{ "data_members", &crt_loc, NO_LIMIT, LIMIT(16384, 127), 0, 0 },
163
	{ "enum_consts", &crt_loc, NO_LIMIT, LIMIT(4096, 127), 0, 0 },
164
	{ "nested_class", &crt_loc, NO_LIMIT, LIMIT(256, 15), 0, 1 },
165
	{ "atexit_funcs", &crt_loc, NO_LIMIT, LIMIT(32, 32), 0, 0 },
166
	{ "base_classes", &crt_loc, NO_LIMIT, LIMIT(16384, 0), 0, 0 },
167
	{ "direct_bases", &crt_loc, NO_LIMIT, LIMIT(1024, 0), 0, 0 },
168
	{ "class_members", &crt_loc, NO_LIMIT, LIMIT(4096, 0), 0, 0 },
169
	{ "virtual_funcs", &crt_loc, NO_LIMIT, LIMIT(16384, 0), 0, 0 },
170
	{ "virtual_bases", &crt_loc, NO_LIMIT, LIMIT(1024, 0), 0, 0 },
171
	{ "static_members", &crt_loc, NO_LIMIT, LIMIT(1024, 0), 0, 0 },
172
	{ "friends", &crt_loc, NO_LIMIT, LIMIT(4096, 0), 0, 0 },
173
	{ "access_declarations", &crt_loc, NO_LIMIT, LIMIT(4096, 0), 0, 0 },
174
	{ "ctor_initializers", &crt_loc, NO_LIMIT, LIMIT(6144, 0), 0, 0 },
175
	{ "scope_qualifiers", &crt_loc, NO_LIMIT, LIMIT(256, 0), 0, 0 },
176
	{ "external_specs", &crt_loc, NO_LIMIT, LIMIT(1024, 0), 0, 1 },
177
	{ "template_pars", &crt_loc, NO_LIMIT, LIMIT(1024, 0), 0, 0 },
178
	{ "instance_depth", &crt_loc, 17, LIMIT(17, 0), 0, 1 },
179
	{ "exception_handlers", &crt_loc, NO_LIMIT, LIMIT(256, 0), 0, 0 },
180
	{ "exception_specs", &crt_loc, NO_LIMIT, LIMIT(256, 0), 0, 0 },
2 7u83 181
 
7 7u83 182
	/* Other quantities */
183
	{ "cast_explicit", &crt_loc, CAST_EXPLICIT, 0, 0, 0 },
184
	{ "maximum_error", &crt_loc, 32, 1, 0, 0 },
185
	{ "tab_width", &crt_loc, 8, 1, 0, 0 },
186
	{ NULL, NULL, 0, 0, 0, 0 }
187
};
2 7u83 188
 
7 7u83 189
#define VALUE_CAT_SIZE		array_size(OPT_VALUE_CATALOG)
2 7u83 190
 
191
 
192
/*
193
    ERROR TYPE CATALOGUE
194
 
195
    This table gives the names of all the types used in the error catalogue
196
    together with the code letter used to encode them.
197
*/
198
 
199
typedef struct {
7 7u83 200
	CONST char *name;
201
	int number;
202
} OPT_TYPE_DATA;
2 7u83 203
 
7 7u83 204
static OPT_TYPE_DATA OPT_TYPE_CATALOG[] = {
205
	{ "ACCESS", ERR_KEY_ACCESS },
206
	{ "BASE_TYPE", ERR_KEY_BASE_TYPE },
207
	{ "CLASS_TYPE", ERR_KEY_CLASS_TYPE },
208
	{ "CV_SPEC", ERR_KEY_CV_SPEC },
209
	{ "DECL_SPEC", ERR_KEY_DECL_SPEC },
210
	{ "FLOAT", ERR_KEY_FLOAT },
211
	{ "HASHID", ERR_KEY_HASHID },
212
	{ "IDENTIFIER", ERR_KEY_IDENTIFIER },
213
	{ "LEX", ERR_KEY_LEX },
214
	{ "LONG_ID", ERR_KEY_LONG_ID },
215
	{ "NAMESPACE", ERR_KEY_NAMESPACE },
216
	{ "NAT", ERR_KEY_NAT },
217
	{ "PPTOKEN_P", ERR_KEY_PPTOKEN_P },
218
	{ "PTR_LOC", ERR_KEY_PTR_LOC },
219
	{ "QUALIFIER", ERR_KEY_QUALIFIER },
220
	{ "STRING", ERR_KEY_STRING },
221
	{ "TYPE", ERR_KEY_TYPE },
222
	{ "cint", ERR_KEY_cint },
223
	{ "cstring", ERR_KEY_cstring },
224
	{ "string", ERR_KEY_string },
225
	{ "ucint", ERR_KEY_ucint },
226
	{ "ulong", ERR_KEY_ulong },
227
	{ "unsigned", ERR_KEY_unsigned },
228
	{ "plural", ERR_KEY_plural }
229
};
2 7u83 230
 
7 7u83 231
#define TYPE_CAT_SIZE		array_size(OPT_TYPE_CATALOG)
2 7u83 232
 
233
 
234
/*
235
    OPTION NAME HASH TABLE
236
 
237
    This hash table is used to hold the names of the various options in
238
    the option catalogue.
239
*/
240
 
241
typedef struct opt_hash_tag {
7 7u83 242
	int number;
243
	OPT_DATA *entry;
244
	struct opt_hash_tag *next;
245
} OPT_HASH;
2 7u83 246
 
7 7u83 247
#define HASH_OPTION	128
248
static OPT_HASH *option_hash[HASH_OPTION + 1];
249
static OPT_HASH *all_option_hash = NULL;
2 7u83 250
 
251
 
252
/*
253
    INITIALISE THE OPTION HASH TABLE
254
 
255
    This routine sets up the option hash table.
256
*/
257
 
7 7u83 258
static void
259
init_opt_hash(void)
2 7u83 260
{
7 7u83 261
	int i;
262
	OPT_DATA *cat = OPT_CATALOG;
263
	OPT_HASH *opt = xmalloc_nof(OPT_HASH, CATALOG_SIZE);
264
	for (i = 0; i <= HASH_OPTION; i++) {
265
		option_hash[i] = NULL;
2 7u83 266
	}
7 7u83 267
	all_option_hash = opt;
268
	for (i = 0; i < CATALOG_SIZE; i++) {
269
		unsigned long h;
270
		string s = ustrlit(cat->name);
271
		if (s) {
272
			h = hash(s);
273
			h %= HASH_OPTION;
274
		} else {
275
			h = HASH_OPTION;
276
		}
277
		opt->number = i;
278
		opt->entry = cat;
279
		opt->next = option_hash[h];
280
		option_hash[h] = opt;
281
		cat++;
282
		opt++;
283
	}
284
	return;
2 7u83 285
}
286
 
287
 
288
/*
289
    FIND AN OPTION NUMBER
290
 
291
    This routine finds the option number corresponding to the string
292
    literal expression s.  n gives a likely value to try first.  It
293
    returns -1 if s is not the name of a known option.
294
*/
295
 
7 7u83 296
int
297
find_option_no(STRING s, int n)
2 7u83 298
{
7 7u83 299
	unsigned kind = DEREF_unsigned(str_simple_kind(s));
300
	if (kind == STRING_NONE) {
301
		OPT_HASH *opt;
302
		unsigned long h;
303
		string text = DEREF_string(str_simple_text(s));
304
		ulong len = DEREF_ulong(str_simple_len(s));
305
		if (n >= 0 && n < CATALOG_SIZE) {
306
			string nm = ustrlit(OPT_CATALOG[n].name);
307
			if (nm && ustreq(text, nm)) {
308
				if (len == (ulong)ustrlen(nm)) {
309
					return (n);
310
				}
311
			}
2 7u83 312
		}
7 7u83 313
		if (all_option_hash == NULL) {
314
			init_opt_hash();
315
		}
316
		h = hash(text);
317
		h %= HASH_OPTION;
318
		for (opt = option_hash[h]; opt != NULL; opt = opt->next) {
319
			string nm = ustrlit(opt->entry->name);
320
			if (nm && ustreq(text, nm)) {
321
				if (len == (ulong)ustrlen(nm)) {
322
					return (opt->number);
323
				}
324
			}
325
		}
2 7u83 326
	}
7 7u83 327
	return (-1);
2 7u83 328
}
329
 
330
 
331
/*
332
    FIND A VALUE OPTION NUMBER
333
 
334
    This routine finds the value option number corresponding to the
335
    string literal expression s.  n gives a likely value to try first.
336
    It returns -1 if s is not the name of a known value option.  Note
337
    that there are not enough cases to warrant a hash table.
338
*/
339
 
7 7u83 340
int
341
find_value_no(STRING s, int n)
2 7u83 342
{
7 7u83 343
	unsigned kind = DEREF_unsigned(str_simple_kind(s));
344
	if (kind == STRING_NONE) {
345
		int i;
346
		OPT_VALUE_DATA *p = OPT_VALUE_CATALOG;
347
		string text = DEREF_string(str_simple_text(s));
348
		ulong len = DEREF_ulong(str_simple_len(s));
349
		if (n >= 0 && n < VALUE_CAT_SIZE) {
350
			string nm = ustrlit(p[n].name);
351
			if (nm && ustreq(text, nm)) {
352
				if (len == (ulong)ustrlen(nm)) {
353
					return (n);
354
				}
355
			}
356
		}
357
		for (i = 0; i < VALUE_CAT_SIZE; i++) {
358
			string nm = ustrlit(p->name);
359
			if (nm && ustreq(text, nm)) {
360
				if (len == (ulong)ustrlen(nm)) {
361
					return (i);
362
				}
363
			}
364
			p++;
365
		}
2 7u83 366
	}
7 7u83 367
	return (-1);
2 7u83 368
}
369
 
370
 
371
/*
372
    FIND A ERROR TYPE NUMBER
373
 
374
    This routine finds the encoding character for the type corresponding
375
    to the string literal expression s.  It returns -1 if s is not the
376
    name of a known value option.  Note that there are not enough cases
377
    to warrant a hash table.
378
*/
379
 
7 7u83 380
int
381
find_type_no(STRING s)
2 7u83 382
{
7 7u83 383
	unsigned kind = DEREF_unsigned(str_simple_kind(s));
384
	if (kind == STRING_NONE) {
385
		int i;
386
		OPT_TYPE_DATA *p = OPT_TYPE_CATALOG;
387
		string text = DEREF_string(str_simple_text(s));
388
		ulong len = DEREF_ulong(str_simple_len(s));
389
		for (i = 0; i < TYPE_CAT_SIZE; i++) {
390
			string nm = ustrlit(p->name);
391
			if (nm && ustreq(text, nm)) {
392
				if (len == (ulong)ustrlen(nm)) {
393
					return (p->number);
394
				}
395
			}
396
			p++;
2 7u83 397
		}
398
	}
7 7u83 399
	return (-1);
2 7u83 400
}
401
 
402
 
403
/*
404
    CURRENT OPTION STATE
405
 
406
    The variable crt_opts is used to record the current option state.
407
    In addition a list of all scopes defined, all_opts, is maintained.
408
    The variable crt_opt shadows crt_opts->opt and gives a user-accessible
409
    array of option values.
410
*/
411
 
7 7u83 412
OPTIONS *crt_opts = NULL;
413
OPTIONS *real_opts = NULL;
414
static OPTIONS *all_opts = NULL;
415
OPTION *crt_opt = NULL;
2 7u83 416
 
417
 
418
/*
419
    SET AN ERROR TO AN OPTION LEVEL
420
 
421
    This routine modifies the severity level of the error err using the
422
    option n.  Whether the severity is set to that of option n depends
423
    on the value of set; it is always set if set is zero, only set if
424
    option n is more severe if set is positive, and only set if option
425
    n is less severe if set is negative.
426
*/
427
 
7 7u83 428
ERROR
429
set_severity(ERROR err, int n, int set)
2 7u83 430
{
7 7u83 431
	if (!IS_NULL_err(err)) {
432
		OPTION opt = crt_opts->opt[n];
433
		int e = error_severity[opt];
434
		if (set != 0) {
435
			/* Compare with previous severity */
436
			int c = DEREF_int(err_severity(err));
437
			if (set > 0) {
438
				if (e < c) {
439
					e = c;
440
				}
441
			} else {
442
				if (e > c) {
443
					e = c;
444
				}
445
			}
446
		}
447
		if (e == ERROR_NONE) {
448
			/* Option off - return null error */
449
			destroy_error(err, 1);
450
			err = NULL_err;
451
		} else {
452
			/* Set severity level */
453
			COPY_int(err_severity(err), e);
454
		}
2 7u83 455
	}
7 7u83 456
	return (err);
2 7u83 457
}
458
 
459
 
460
/*
461
    PERFORM ACTIONS FOR AN OPTION
462
 
463
    This routine performs any actions associated with setting the value
464
    of option n to opt.  The flag end is true if this call is at the
465
    end of a scope to restore the old value of option n.
466
*/
467
 
7 7u83 468
static void
469
action_option(int n, unsigned opt, int end)
2 7u83 470
{
7 7u83 471
	switch (n) {
472
	case OPT_none: {
473
		error_severity[OPTION_OFF] = default_severity[opt];
474
		break;
2 7u83 475
	}
7 7u83 476
	case OPT_warning: {
477
		error_severity[OPTION_WARN] = default_severity[opt];
478
		break;
2 7u83 479
	}
7 7u83 480
	case OPT_error: {
481
		error_severity[OPTION_ON] = default_severity[opt];
482
		break;
2 7u83 483
	}
7 7u83 484
	case OPT_whatever: {
485
		error_severity[OPTION_WHATEVER] = default_severity[opt];
486
		break;
2 7u83 487
	}
7 7u83 488
	case OPT_conv_int_int_expl:
489
	case OPT_conv_int_int_impl:
490
	case OPT_conv_int_ptr_expl:
491
	case OPT_conv_ptr_ptr_expl: {
492
		/* Individual conversion options */
493
		if (!end) {
494
			OPTION *q = real_opts->opt;
495
			OPTION c = OPTION_OFF;
496
			OPTION c1 = OPTION_OFF;
497
			OPTION c2 = q[OPT_conv_int_ptr_expl];
498
			OPTION c3 = q[OPT_conv_ptr_ptr_expl];
499
			OPTION c11 = q[OPT_conv_int_int_expl];
500
			OPTION c12 = q[OPT_conv_int_int_impl];
501
			if (c11 || c12) {
502
				c1 = OPTION_ON;
503
			}
504
			if (c1 || c2 || c3) {
505
				c = OPTION_ON;
506
			}
507
			q[OPT_conv_ptr_ptr] = c3;
508
			q[OPT_conv_int_ptr] = c2;
509
			q[OPT_conv_int_int] = c1;
510
			q[OPT_conv] = c;
511
		}
512
		break;
2 7u83 513
	}
7 7u83 514
	case OPT_discard_func:
515
	case OPT_discard_static:
516
	case OPT_discard_value: {
517
		/* Individual discard options */
518
		if (!end) {
519
			OPTION *q = real_opts->opt;
520
			OPTION d = OPTION_OFF;
521
			OPTION d1 = OPTION_OFF;
522
			OPTION d2 = q[OPT_discard_static];
523
			OPTION d11 = q[OPT_discard_func];
524
			OPTION d12 = q[OPT_discard_value];
525
			if (d11 || d12) {
526
				d1 = OPTION_ON;
527
			}
528
			if (d1 || d2) {
529
				d = OPTION_ON;
530
			}
531
			q[OPT_discard_exp] = d1;
532
			q[OPT_discard] = d;
533
		}
534
		break;
2 7u83 535
	}
7 7u83 536
	case OPT_const_internal: {
537
		/* Linkage of const objects */
538
		if (opt == OPTION_ON) {
539
			const_linkage = dspec_static;
540
		} else {
541
			const_linkage = dspec_extern;
542
		}
543
		break;
2 7u83 544
	}
7 7u83 545
	case OPT_inline_internal: {
546
		/* Linkage of inline functions */
547
		if (opt == OPTION_ON) {
548
			inline_linkage = dspec_static;
549
		} else {
550
			inline_linkage = dspec_extern;
551
		}
552
		break;
2 7u83 553
	}
7 7u83 554
	case OPT_decl_volatile: {
555
		/* Volatility of external objects */
556
		if (opt == OPTION_ON) {
557
			cv_extern = cv_volatile;
558
		} else {
559
			cv_extern = cv_none;
560
		}
561
		break;
2 7u83 562
	}
7 7u83 563
	case OPT_proto_scope: {
564
		/* Recalculate namespaces */
565
		update_namespace();
566
		break;
2 7u83 567
	}
7 7u83 568
	case OPT_cpplus_comment: {
569
		/* C++ comments */
570
		allow_cpp_comments = (opt != OPTION_DISALLOW);
571
		break;
2 7u83 572
	}
7 7u83 573
	case OPT_digraph: {
574
		/* Digraphs */
575
		allow_digraphs = (opt != OPTION_DISALLOW);
576
		break;
2 7u83 577
	}
7 7u83 578
	case OPT_dollar_ident: {
579
		/* Dollar in identifier */
580
		int c = char_z;
581
		if (opt == OPTION_DISALLOW) {
582
			c = char_dollar;
583
		}
584
		set_char_lookup(char_dollar, c);
585
		break;
2 7u83 586
	}
7 7u83 587
	case OPT_iso_keyword: {
588
		/* ISO keywords */
589
		allow_iso_keywords = (opt != OPTION_DISALLOW);
590
		break;
2 7u83 591
	}
7 7u83 592
	case OPT_lint_comment: {
593
		/* Lint comments */
594
		analyse_comments = (opt != OPTION_DISALLOW);
595
		break;
2 7u83 596
	}
7 7u83 597
	case OPT_longlong: {
598
		/* 'long long' types */
599
		int key = (opt != OPTION_DISALLOW);
600
		basetype_info[ntype_sllong].key = key;
601
		basetype_info[ntype_ullong].key = key;
602
		break;
2 7u83 603
	}
7 7u83 604
	case OPT_trigraph: {
605
		/* Trigraphs */
606
		allow_trigraphs = (opt != OPTION_DISALLOW);
607
		break;
2 7u83 608
	}
7 7u83 609
	}
610
	return;
2 7u83 611
}
612
 
613
 
614
/*
615
    SET AN OPTION LEVEL
616
 
617
    This routine sets the option n to option level opt.  This can be
618
    OPTION_OFF (for 'off' or 'allow'), OPTION_WARN (for 'warning') or
619
    OPTION_ON (for 'on' or 'disallow').  Note that special action needs
620
    to be taken if n represents a set of options such as conv or discard
621
    where the set value is the logical or of the values of the set
622
    members.
623
*/
624
 
7 7u83 625
void
626
set_option(int n, unsigned opt)
2 7u83 627
{
7 7u83 628
	if (n != -1) {
629
		/* Set the option level */
630
		switch (n) {
631
		case OPT_conv: {
632
			/* All conversion options */
633
			set_option(OPT_conv_int_int_expl, opt);
634
			set_option(OPT_conv_int_int_impl, opt);
635
			set_option(OPT_conv_int_ptr_expl, opt);
636
			set_option(OPT_conv_ptr_ptr_expl, opt);
637
			break;
2 7u83 638
		}
7 7u83 639
		case OPT_conv_int_int: {
640
			/* All integer conversion options */
641
			set_option(OPT_conv_int_int_expl, opt);
642
			set_option(OPT_conv_int_int_impl, opt);
643
			break;
644
		}
645
		case OPT_conv_int_ptr: {
646
			/* All integer to pointer conversion options */
647
			set_option(OPT_conv_int_ptr_expl, opt);
648
			break;
649
		}
650
		case OPT_conv_ptr_ptr: {
651
			/* All pointer conversion options */
652
			set_option(OPT_conv_ptr_ptr_expl, opt);
653
			break;
654
		}
655
		case OPT_discard: {
656
			/* All discard options */
657
			set_option(OPT_discard_func, opt);
658
			set_option(OPT_discard_static, opt);
659
			set_option(OPT_discard_value, opt);
660
			break;
661
		}
662
		case OPT_discard_exp: {
663
			/* Expression discard options */
664
			set_option(OPT_discard_func, opt);
665
			set_option(OPT_discard_value, opt);
666
			break;
667
		}
668
		case OPT_func_impl: {
669
			/* These options are negated */
670
			if (opt == OPTION_ON) {
671
				opt = OPTION_OFF;
672
			} else if (opt == OPTION_OFF) {
673
				opt = OPTION_ON;
2 7u83 674
			}
7 7u83 675
			goto default_lab;
2 7u83 676
		}
7 7u83 677
		default:
678
default_lab: {
679
		     /* Simple options */
680
		     OPTIONS *p = crt_opts;
681
		     if (OPT_CATALOG[n].scoped) {
682
			     /* Scoped options */
683
			     int sev = (int)p->set[n];
684
			     OPTION new_opt = (OPTION)opt;
685
			     OPTION old_opt = p->opt[n];
686
			     if (new_opt != old_opt) {
687
				     /* Option value changed */
688
				     p->opt[n] = new_opt;
689
				     action_option(n, opt, 0);
690
			     }
691
			     if (sev != ERROR_WHATEVER) {
692
				     /* Option already set in this scope */
693
				     string s = ustrlit(OPT_CATALOG[n].name);
694
				     ERROR err = ERR_pragma_scope_set(s);
695
				     if (!IS_NULL_err(err)) {
696
					     COPY_int(err_severity(err), sev);
697
					     report(preproc_loc, err);
698
				     }
699
			     }
700
			     p->set[n] = ERROR_SERIOUS;
701
		     } else {
702
			     /* Unscoped options */
703
			     p->opt[n] = (OPTION)opt;
704
			     action_option(n, opt, 0);
705
			     p->set[n] = ERROR_SERIOUS;
706
		     }
707
		     break;
708
	     }
709
		}
2 7u83 710
	}
7 7u83 711
	return;
2 7u83 712
}
713
 
714
 
715
/*
716
    PERFORM ACTIONS FOR AN OPTION VALUE
717
 
718
    This routine performs any actions associated with setting option value
719
    n to v.  The flag end is true if this call is at the end of a scope to
720
    restore the old value of option n.
721
*/
722
 
7 7u83 723
static void
724
action_value(int n, unsigned long v)
2 7u83 725
{
7 7u83 726
	switch (n) {
727
	case OPT_VAL_include_depth: {
728
		set_incl_depth(v);
729
		break;
2 7u83 730
	}
7 7u83 731
	case OPT_VAL_name_limit: {
732
		if (v < max_id_length) {
733
			max_id_length = v;
734
		}
735
		break;
2 7u83 736
	}
7 7u83 737
	case OPT_VAL_maximum_error: {
738
		max_errors = v;
739
		break;
2 7u83 740
	}
7 7u83 741
	case OPT_VAL_tab_width: {
742
		if (v != 0) {
743
			tab_width = v;
744
		}
745
		break;
2 7u83 746
	}
7 7u83 747
	}
748
	return;
2 7u83 749
}
750
 
751
 
752
/*
753
    SET OPTION VALUE
754
 
755
    This routine sets the option value for option n to the integer literal
756
    expression e or the value v.  Note that option values are not scoped.
757
*/
758
 
7 7u83 759
void
760
set_value(int n, EXP e, unsigned long v)
2 7u83 761
{
7 7u83 762
	if (!IS_NULL_exp(e)) {
763
		NAT m;
764
		if (!IS_exp_int_lit(e)) {
765
			return;
766
		}
767
		m = DEREF_nat(exp_int_lit_nat(e));
768
		v = get_nat_value(m);
769
	}
770
	if (n != -1) {
771
		OPT_VALUE_CATALOG[n].max_value = v;
772
		OPT_VALUE_CATALOG[n].min_value = v;
773
		action_value(n, v);
774
	}
775
	return;
2 7u83 776
}
777
 
778
 
779
/*
780
    CHECK AN OPTION VALUE
781
 
782
    This routine checks whether the value v is less than the maximum
783
    permitted value for the option n.  It returns true if so.  Extra
784
    arguments for use in error reporting may be provided.
785
*/
786
 
7 7u83 787
int
788
check_value(int n, unsigned long v, ...) /* VARARGS */
2 7u83 789
{
7 7u83 790
	va_list args;
791
	unsigned long u;
792
	OPT_VALUE_DATA *p;
2 7u83 793
#if FS_STDARG
7 7u83 794
	va_start(args, v);
2 7u83 795
#else
7 7u83 796
	int n;
797
	unsigned long v;
798
	va_start(args);
799
	n = va_arg(args, int);
800
	v = va_arg(args, unsigned long);
2 7u83 801
#endif
802
 
7 7u83 803
	/* Check against implementation limit */
804
	p = OPT_VALUE_CATALOG + n;
805
	u = p->max_value;
806
	if (v > u) {
807
		int err = 1;
808
		if (p->incr) {
809
			if (v > u + 1) {
810
				err = 0;
811
			}
812
			p->incr = 2;
2 7u83 813
		}
7 7u83 814
		if (err) {
815
			LOCATION *loc = p->loc;
816
			switch (n) {
817
			case OPT_VAL_include_depth: {
818
				/* Include depth too great */
819
				print_error(loc, ERR_cpp_include_depth(v));
820
				break;
821
			}
822
			case OPT_VAL_name_limit: {
823
				/* Name length too great */
824
				HASHID nm = va_arg(args, HASHID);
825
				print_error(loc, ERR_lex_name_limit(nm, v, u));
826
				break;
827
			}
828
			case OPT_VAL_instance_depth: {
829
				/* Instantiation depth too great */
830
				print_error(loc, ERR_temp_inst_depth(v));
831
				break;
832
			}
833
			default : {
834
				/* Other limit exceeded */
835
				string s = ustrlit(p->name);
836
				print_error(loc, ERR_limits_max(s, v, u));
837
				break;
838
			}
839
			}
2 7u83 840
		}
7 7u83 841
		va_end(args);
842
		return (0);
2 7u83 843
	}
844
 
7 7u83 845
	/* Check against minimum implementation limit */
846
	u = p->min_value;
847
	if (v > u) {
848
		if (p->incr) {
849
			p->incr = 2;
850
		} else {
851
			LOCATION *loc = p->loc;
852
			string s = ustrlit(p->name);
853
			print_error(loc, ERR_limits_min(s, v, u));
854
		}
2 7u83 855
	}
7 7u83 856
	va_end(args);
857
	return (1);
2 7u83 858
}
859
 
860
 
861
/*
862
    INCREMENT AN OPTION VALUE
863
 
864
    This routine increments the current value of the option value n,
865
    applying check_value to the result.
866
*/
867
 
7 7u83 868
int
869
incr_value(int n)
2 7u83 870
{
7 7u83 871
	OPT_VALUE_DATA *p = OPT_VALUE_CATALOG + n;
872
	unsigned long v = ++(p->crt_value);
873
	ASSERT(p->incr);
874
	return (check_value(n, v));
2 7u83 875
}
876
 
877
 
878
/*
879
    DECREMENT AN OPTION VALUE
880
 
881
    This routine decrements the current value of the option value n.
882
*/
883
 
7 7u83 884
void
885
decr_value(int n)
2 7u83 886
{
7 7u83 887
	OPT_VALUE_DATA *p = OPT_VALUE_CATALOG + n;
888
	unsigned long v = p->crt_value;
889
	if (v) {
890
		if (p->incr == 2) {
891
			/* Report maximum value attained */
892
			LOCATION *loc = p->loc;
893
			string s = ustrlit(p->name);
894
			unsigned long u = p->min_value;
895
			print_error(loc, ERR_limits_min(s, v, u));
896
			p->incr = 1;
897
		}
898
		p->crt_value = v - 1;
2 7u83 899
	}
7 7u83 900
	return;
2 7u83 901
}
902
 
903
 
904
/*
905
    SET LINKAGE OPTION
906
 
907
    This routine sets the current external linkage option to ds.
908
*/
909
 
7 7u83 910
void
911
set_link_opt(DECL_SPEC ds)
2 7u83 912
{
7 7u83 913
	OPTIONS *p = crt_opts;
914
	if (p) {
915
		DECL_SPEC ods = p->lnk_opt[1];
916
		if (ods != dspec_ignore) {
917
			/* Option already set in this scope */
918
			string s = ustrlit("link_extern");
919
			ERROR err = ERR_pragma_scope_set(s);
920
			if (!IS_NULL_err(err)) {
921
				report(preproc_loc, err);
922
			}
923
		}
924
		p->lnk_opt[1] = ds;
925
		crt_linkage = ds;
926
		new_linkage = ds;
2 7u83 927
	}
7 7u83 928
	return;
2 7u83 929
}
930
 
931
 
932
/*
933
    FIND A NAMED CHECKING SCOPE
934
 
935
    This routine searches for a checking scope named nm, returning the
936
    corresponding table of options.  If nm has not been defined then the
937
    null pointer is returned.
938
*/
939
 
7 7u83 940
static OPTIONS *
941
find_option(HASHID nm)
2 7u83 942
{
7 7u83 943
	OPTIONS *p;
944
	for (p = all_opts; p != NULL; p = p->next) {
945
		if (EQ_hashid(nm, p->name)) {
946
			return (p);
947
		}
948
	}
949
	return (NULL);
2 7u83 950
}
951
 
952
 
953
/*
954
    CREATE A NEW OPTION
955
 
956
    This routine creates a new option scope named nm with initial
957
    values taken either from the existing scope q or, if this is the
958
    null pointer, the nth entry of the options catalogue above.
959
*/
960
 
7 7u83 961
static OPTIONS *
962
new_option(HASHID nm, OPTIONS *q, int n)
2 7u83 963
{
7 7u83 964
	/* Allocate space for new scope */
965
	int i;
966
	OPTIONS *p = xmalloc_nof(OPTIONS, 1);
967
	OPTION *po = xmalloc_nof(OPTION, 2 * CATALOG_SIZE);
968
	OPTION *ps = po + CATALOG_SIZE;
969
	p->opt = po;
970
	p->set = ps;
971
	p->val_opt[0] = no_declarations;
972
	p->lnk_opt[0] = crt_linkage;
973
	p->lnk_opt[1] = dspec_ignore;
974
	p->prev = NULL;
975
	p->name = NULL_hashid;
976
	p->next = all_opts;
977
	all_opts = p;
2 7u83 978
 
7 7u83 979
	/* Check scope name */
980
	if (!IS_NULL_hashid(nm)) {
981
		if (find_option(nm)) {
982
			report(preproc_loc, ERR_pragma_scope_redef(nm));
983
		}
984
		p->name = nm;
2 7u83 985
	}
986
 
7 7u83 987
	/* Set up scope */
988
	if (q) {
989
		/* Copy existing scope */
990
		OPTION *qo = q->opt;
991
		for (i = 0; i < CATALOG_SIZE; i++) {
992
			*(po++) = *(qo++);
993
			*(ps++) = ERROR_WHATEVER;
994
		}
995
	} else {
996
		/* Use standard scope */
997
		OPT_DATA *cat = OPT_CATALOG;
998
		for (i = 0; i < CATALOG_SIZE; i++) {
999
			/* Use the nth entry from the catalogue */
1000
			*(po++) = cat->def[n];
1001
			*(ps++) = ERROR_SERIOUS;
1002
			cat++;
1003
		}
2 7u83 1004
	}
7 7u83 1005
	return (p);
2 7u83 1006
}
1007
 
1008
 
1009
/*
1010
    BEGIN A CHECKING SCOPE
1011
 
1012
    This routine begins a new checking scope.
1013
*/
1014
 
7 7u83 1015
void
1016
begin_option(IDENTIFIER id)
2 7u83 1017
{
7 7u83 1018
	OPTIONS *p;
1019
	HASHID nm = NULL_hashid;
1020
	if (!IS_NULL_id(id)) {
1021
		nm = DEREF_hashid(id_name(id));
1022
	}
1023
	p = new_option(nm, real_opts, 0);
1024
	p->prev = real_opts;
1025
	crt_opts = p;
1026
	real_opts = p;
1027
	crt_opt = p->opt;
1028
	return;
2 7u83 1029
}
1030
 
1031
 
1032
/*
1033
    END A CHECKING SCOPE
1034
 
1035
    This routine ends the current checking scope.
1036
*/
1037
 
7 7u83 1038
void
1039
end_option(int expl)
2 7u83 1040
{
7 7u83 1041
	OPTIONS *p = real_opts;
1042
	if (p) {
1043
		OPTIONS *q = p->prev;
1044
		DECL_SPEC ds = p->lnk_opt[0];
1045
		if (expl && p->val_opt[0] == no_declarations) {
1046
			if (IS_NULL_hashid(p->name) && !preproc_only) {
1047
				report(preproc_loc, ERR_dcl_dcl_none());
2 7u83 1048
			}
1049
		}
7 7u83 1050
		crt_linkage = ds;
1051
		new_linkage = ds;
1052
		if (q) {
1053
			int i;
1054
			crt_opts = q;
1055
			real_opts = q;
1056
			crt_opt = q->opt;
1057
			for (i = 0; i < CATALOG_SIZE; i++) {
1058
				if (p->set[i]!= ERROR_WHATEVER) {
1059
					/* Restore old option value */
1060
					OPTION opt_old = p->opt[i];
1061
					OPTION opt_new = q->opt[i];
1062
					if (opt_new != opt_old) {
1063
						if (OPT_CATALOG[i].scoped) {
1064
							action_option(i,
1065
							  (unsigned)opt_new, 1);
1066
						} else {
1067
							q->opt[i] = opt_old;
1068
							q->set[i] = 1;
1069
						}
1070
					}
1071
				}
1072
			}
1073
			return;
1074
		}
2 7u83 1075
	}
7 7u83 1076
	report(preproc_loc, ERR_pragma_scope_end());
1077
	return;
2 7u83 1078
}
1079
 
1080
 
1081
/*
1082
    USE A CHECKING SCOPE
1083
 
1084
    This routine brings the set of checks given by p into the current
1085
    checking scope.  e indicates the error severity with which to report
1086
    reset options.
1087
*/
1088
 
7 7u83 1089
void
1090
use_mode(OPTIONS *p, int e)
2 7u83 1091
{
7 7u83 1092
	int i;
1093
	OPTIONS *q = real_opts;
1094
	DECL_SPEC ds = p->lnk_opt[1];
1095
	if (ds != dspec_ignore) {
1096
		DECL_SPEC ods = q->lnk_opt[1];
1097
		if (ods != dspec_ignore) {
1098
			/* Option already set in this scope */
1099
			string s = ustrlit("link_extern");
1100
			ERROR err = ERR_pragma_scope_set(s);
1101
			if (!IS_NULL_err(err)) {
1102
				COPY_int(err_severity(err), e);
1103
				report(preproc_loc, err);
1104
			}
1105
		}
1106
		q->lnk_opt[1] = ds;
1107
		crt_linkage = ds;
1108
		new_linkage = ds;
2 7u83 1109
	}
7 7u83 1110
	for (i = 0; i < CATALOG_SIZE; i++) {
1111
		if (p->set[i]!= ERROR_WHATEVER && OPT_CATALOG[i].scoped) {
1112
			OPTION new_opt = p->opt[i];
1113
			OPTION old_opt = q->opt[i];
1114
			if (new_opt != old_opt) {
1115
				/* Option value changed */
1116
				q->opt[i] = new_opt;
1117
				action_option(i,(unsigned)new_opt, 0);
1118
			}
1119
			if (q->set[i]!= ERROR_WHATEVER && e != ERROR_NONE) {
1120
				/* Option already set in this scope */
1121
				string s = ustrlit(OPT_CATALOG[i].name);
1122
				ERROR err = ERR_pragma_scope_set(s);
1123
				if (!IS_NULL_err(err)) {
1124
					COPY_int(err_severity(err), e);
1125
					report(preproc_loc, err);
1126
				}
1127
			}
1128
			q->set[i] = ERROR_SERIOUS;
2 7u83 1129
		}
1130
	}
7 7u83 1131
	return;
2 7u83 1132
}
1133
 
1134
 
1135
/*
1136
    SET CURRENT CHECKING SCOPE
1137
 
1138
    This routine sets the current checking scope to p.  It is used in
1139
    context switching in macro expansion.
1140
*/
1141
 
7 7u83 1142
void
1143
set_mode(OPTIONS *p)
2 7u83 1144
{
7 7u83 1145
	if (p) {
1146
		crt_opts = p;
1147
		crt_opt = p->opt;
1148
	}
1149
	return;
2 7u83 1150
}
1151
 
1152
 
1153
/*
1154
    USE A NAMED CHECKING SCOPE
1155
 
1156
    This routine brings the named checking scope id back into scope.  The
1157
    opt argument describes how the resetting of these options are to be
1158
    handled.
1159
*/
1160
 
7 7u83 1161
void
1162
use_option(IDENTIFIER id, unsigned opt)
2 7u83 1163
{
7 7u83 1164
	HASHID nm = DEREF_hashid(id_name(id));
1165
	OPTIONS *p = find_option(nm);
1166
	if (p == NULL) {
1167
		report(preproc_loc, ERR_pragma_scope_undef(nm));
1168
		return;
1169
	}
1170
	use_mode(p, error_severity[opt]);
1171
	return;
2 7u83 1172
}
1173
 
1174
 
1175
/*
1176
    ASSOCIATE A CHECKING SCOPE WITH A DIRECTORY
1177
 
1178
    This routine associates the named checking scope id with the named
1179
    include file directory dir.
1180
*/
1181
 
7 7u83 1182
void
1183
directory_option(IDENTIFIER dir, IDENTIFIER id)
2 7u83 1184
{
7 7u83 1185
	string s;
1186
	HASHID nm = DEREF_hashid(id_name(id));
1187
	OPTIONS *p = find_option(nm);
1188
	if (p == NULL) {
1189
		report(preproc_loc, ERR_pragma_scope_undef(nm));
1190
	}
1191
	nm = DEREF_hashid(id_name(dir));
1192
	s = DEREF_string(hashid_name_etc_text(nm));
1193
	directory_mode(s, p);
1194
	return;
2 7u83 1195
}
1196
 
1197
 
1198
/*
1199
    INITIALISE OPTIONS
1200
 
1201
    This routine initialises the outer checking scope at the checking
1202
    level indicated by level and sets up the option hash table.
1203
*/
1204
 
7 7u83 1205
void
1206
init_option(int level)
2 7u83 1207
{
7 7u83 1208
	int i;
1209
	string s;
1210
	HASHID nm;
1211
	OPTION *po;
1212
	OPTIONS *p1, *p2;
1213
	OPT_DATA *cat = OPT_CATALOG;
1214
	OPT_VALUE_DATA *vcat = OPT_VALUE_CATALOG;
2 7u83 1215
 
7 7u83 1216
	/* Mark basic options */
1217
	cat[OPT_none].scoped = 0;
1218
	cat[OPT_warning].scoped = 0;
1219
	cat[OPT_error].scoped = 0;
1220
	cat[OPT_whatever].scoped = 0;
2 7u83 1221
 
7 7u83 1222
	/* Mark unscoped options */
1223
	cat[OPT_const_internal].scoped = 0;
1224
	cat[OPT_cpplus_comment].scoped = 0;
1225
	cat[OPT_digraph].scoped = 0;
1226
	cat[OPT_dollar_ident].scoped = 0;
1227
	cat[OPT_ellipsis_ident].scoped = 0;
1228
	cat[OPT_inline_internal].scoped = 0;
1229
	cat[OPT_iso_keyword].scoped = 0;
1230
	cat[OPT_lint_comment].scoped = 0;
1231
	cat[OPT_trigraph].scoped = 0;
2 7u83 1232
 
7 7u83 1233
	/* A few other initialisations */
1234
	max_id_length = vcat[OPT_VAL_name_limit].min_value;
2 7u83 1235
 
7 7u83 1236
	/* Set up default compilation modes */
1237
	s = ustrlit("__DEFAULT__");
1238
	nm = lookup_name(s, hash(s), 0, lex_identifier);
1239
	p1 = new_option(nm, NIL(OPTIONS), 0);
1240
	s = ustrlit("__ALL__");
1241
	nm = lookup_name(s, hash(s), 0, lex_identifier);
1242
	p2 = new_option(nm, NIL(OPTIONS), 1);
2 7u83 1243
 
7 7u83 1244
	/* Bring option into scope */
1245
	if (level == 1) {
1246
		p1 = p2;
1247
	}
1248
	p1 = new_option(NULL_hashid, p1, 0);
1249
	crt_opts = p1;
1250
	real_opts = p1;
1251
	po = p1->opt;
1252
	crt_opt = po;
1253
	for (i = 0; i < CATALOG_SIZE; i++) {
1254
		OPTION e = *(po++);
1255
		action_option(i, (unsigned)e, 0);
1256
	}
1257
	for (i = 0; i < VALUE_CAT_SIZE; i++) {
1258
		action_value(i, vcat->max_value);
1259
		vcat++;
1260
	}
1261
	return;
2 7u83 1262
}
1263
 
1264
 
1265
/*
1266
    TERMINATE OPTIONS
1267
 
1268
    This routine calls end_option for all unterminated checking scopes.
1269
    It also reports any implementation limits which have been exceeded
1270
    but not previously reported.
1271
*/
1272
 
7 7u83 1273
void
1274
term_option(void)
2 7u83 1275
{
7 7u83 1276
	if (real_opts) {
1277
		int i;
1278
		int expl = 1;
1279
		OPT_VALUE_DATA *p = OPT_VALUE_CATALOG;
1280
		for (i = 0; i < VALUE_CAT_SIZE; i++) {
1281
			if (p->incr == 2) {
1282
				/* Implementation limit exceeded */
1283
				string s = ustrlit(p->name);
1284
				unsigned long v = p->crt_value;
1285
				unsigned long u = p->min_value;
1286
				report(preproc_loc, ERR_limits_min(s, v, u));
1287
				p->incr = 1;
1288
			}
1289
			p++;
1290
		}
1291
		while (real_opts->prev) {
1292
			end_option(expl);
1293
			expl = 0;
1294
		}
1295
		if (expl && no_declarations == 0 && !preproc_only) {
1296
			report(preproc_loc, ERR_dcl_dcl_none());
1297
		}
2 7u83 1298
	}
7 7u83 1299
	xfree_nof(all_option_hash);
1300
	all_option_hash = NULL;
1301
	return;
2 7u83 1302
}