Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
#include "config.h"
32
#include "system.h"
33
#include "c_types.h"
34
#include "exp_ops.h"
35
#include "hashid_ops.h"
36
#include "id_ops.h"
37
#include "loc_ext.h"
38
#include "member_ops.h"
39
#include "nat_ops.h"
40
#include "str_ops.h"
41
#include "tok_ops.h"
42
#include "type_ops.h"
43
#include "error.h"
44
#include "catalog.h"
45
#include "option.h"
46
#include "buffer.h"
47
#include "char.h"
48
#include "compile.h"
49
#include "constant.h"
50
#include "convert.h"
51
#include "dump.h"
52
#include "file.h"
53
#include "hash.h"
54
#include "identifier.h"
55
#include "lex.h"
56
#include "literal.h"
57
#include "macro.h"
58
#include "namespace.h"
59
#include "parse.h"
60
#include "pragma.h"
61
#include "predict.h"
62
#include "preproc.h"
63
#include "print.h"
64
#include "statement.h"
65
#include "symbols.h"
66
#include "syntax.h"
67
#include "tokdef.h"
68
#include "token.h"
69
#include "ustring.h"
70
#include "xalloc.h"
71
 
72
 
73
/*
74
    FORWARD DECLARATIONS
75
 
76
    The following functions, which are concerned with processing assertions,
77
    are used in read_if_exp before they are defined.
78
*/
79
 
80
static int eq_pptok PROTO_S ( ( PPTOKEN *, PPTOKEN * ) ) ;
81
static PPTOKEN *skip_predicate PROTO_S ( ( PPTOKEN **, int ) ) ;
82
static int check_assert PROTO_S ( ( HASHID, PPTOKEN *, int ) ) ;
83
 
84
 
85
/*
86
    PREPROCESSING FLAGS
87
 
88
    The flag in_preproc_dir is set to true in a preprocessing directive.
89
    The flag preproc_only causes only the preprocessor to be run.  Finally
90
    preproc_loc records the position of the start of each preprocessing
91
    directive.
92
*/
93
 
94
int in_preproc_dir = 0 ;
95
int no_preproc_dir = 0 ;
96
int in_pragma_dir = 0 ;
97
int in_hash_if_exp = 0 ;
98
int pragma_number = 0 ;
99
int preproc_only = 0 ;
100
int preproc_space = 0 ;
101
LOCATION preproc_loc = NULL_loc ;
102
 
103
 
104
/*
105
    NEGATE A CONDITIONAL
106
 
107
    This routine negates the conditional cond.  Note that skipped and
108
    unresolved conditions negate to themselves.
109
*/
110
 
111
static unsigned negate_cond
112
    PROTO_N ( ( cond ) )
113
    PROTO_T ( unsigned cond )
114
{
115
    if ( cond == PP_TRUE ) return ( PP_FALSE ) ;
116
    if ( cond == PP_FALSE ) return ( PP_TRUE ) ;
117
    if ( cond == PP_PAST ) return ( PP_FALSE ) ;
118
    return ( cond ) ;
119
}
120
 
121
 
122
/*
123
    CONDITIONAL COMPILATION STACK
124
 
125
    The stack preproc_stack gives all the active conditional compilation
126
    states.  In addition loc_stack records the corresponding file locations.
127
    preproc_depth gives the depth of conditional compilation within the
128
    current file.
129
*/
130
 
131
static STACK ( unsigned ) preproc_stack = NULL_stack ( unsigned ) ;
132
static STACK ( LOCATION ) loc_stack = NULL_stack ( LOCATION ) ;
133
static unsigned preproc_depth = 0 ;
134
 
135
 
136
/*
137
    SET UP CONDITIONAL COMPILATION STACK
138
 
139
    This routine sets up the conditional compilation stack at the start
140
    of a source file by pushing an end marker.
141
*/
142
 
143
void start_preproc_if
144
    PROTO_Z ()
145
{
146
    PUSH_unsigned ( preproc_depth, preproc_stack ) ;
147
    PUSH_unsigned ( PP_END, preproc_stack ) ;
148
    PUSH_loc ( crt_loc, loc_stack ) ;
149
    preproc_depth = 0 ;
150
    return ;
151
}
152
 
153
 
154
/*
155
    CLEAR CONDITIONAL COMPILATION STACK
156
 
157
    This routine is called at the end of each source file to check for
158
    any unmatched '#if', '#elif' or '#else' directives.  It clears the
159
    conditional compilation stack down as far as the end marker set up
160
    by the previous routine.  It is possible for the routine to be
161
    called more than once for the main source file, hence the necessity
162
    to check that the stack is not empty.  The routine returns true if
163
    no unmatched directives are found.
164
*/
165
 
166
int clear_preproc_if
167
    PROTO_Z ()
168
{
169
    int ok = 1 ;
170
    while ( !IS_NULL_stack ( preproc_stack ) ) {
171
	int dir ;
172
	LOCATION loc ;
173
	unsigned cond ;
174
	POP_unsigned ( cond, preproc_stack ) ;
175
	POP_loc ( loc, loc_stack ) ;
176
	if ( cond == PP_END ) {
177
	    /* Restore stored preprocessing depth */
178
	    POP_unsigned ( preproc_depth, preproc_stack ) ;
179
	    break ;
180
	}
181
	if ( cond & PP_HAVE_ELSE ) {
182
	    dir = lex_else ;
183
	} else if ( cond & PP_HAVE_ELIF ) {
184
	    dir = lex_elif ;
185
	} else {
186
	    dir = lex_if ;
187
	}
188
	report ( loc, ERR_cpp_cond_if_match ( dir, lex_endif ) ) ;
189
	decr_value ( OPT_VAL_hash_if_depth ) ;
190
	preproc_depth-- ;
191
	ok = 0 ;
192
    }
193
    return ( ok ) ;
194
}
195
 
196
 
197
/*
198
    MACRO-LIKE TOKEN IDENTIFIER
199
 
200
    If check_macro finds a macro-like token then the corresponding identifier
201
    is stored in this variable.
202
*/
203
 
204
IDENTIFIER token_macro = NULL_id ;
205
 
206
 
207
/*
208
    CHECK WHETHER A MACRO IS DEFINED
209
 
210
    This routine checks whether the hash table entry macro represents a
211
    valid macro.  It returns PP_TRUE if macro is already defined and
212
    PP_FALSE otherwise.  It also reports on ISO keywords and other invalid
213
    macro identifiers.  If used is true then the macro is marked as having
214
    been used.
215
*/
216
 
217
unsigned check_macro
218
    PROTO_N ( ( macro, used ) )
219
    PROTO_T ( HASHID macro X int used )
220
{
221
    /* Check for simple macros */
222
    DECL_SPEC ds ;
223
    IDENTIFIER id ;
224
    if ( IS_NULL_hashid ( macro ) ) {
225
	/* Special case for protection macros */
226
	return ( PP_TRUE ) ;
227
    }
228
    id = DEREF_id ( hashid_id ( macro ) ) ;
229
    switch ( TAG_id ( id ) ) {
230
	case id_obj_macro_tag :
231
	case id_func_macro_tag : {
232
	    if ( used ) {
233
		ds = DEREF_dspec ( id_storage ( id ) ) ;
234
		ds |= dspec_used ;
235
		COPY_dspec ( id_storage ( id ), ds ) ;
236
		if ( do_macro && do_usage ) dump_use ( id, &preproc_loc, 1 ) ;
237
	    }
238
	    return ( PP_TRUE ) ;
239
	}
240
	case id_iso_keyword_tag : {
241
	    if ( used ) report ( preproc_loc, ERR_lex_key_iso ( macro ) ) ;
242
	    break ;
243
	}
244
    }
245
 
246
    /* Check for tokenised values */
247
    if ( preproc_only ) {
248
	id = underlying_id ( id ) ;
249
	ds = DEREF_dspec ( id_storage ( id ) ) ;
250
	if ( ds & dspec_token ) {
251
	    /* May be a token */
252
	    token_macro = id ;
253
	    return ( PP_TOKEN | PP_UNRESOLVED ) ;
254
	}
255
 
256
    } else {
257
	id = find_id ( macro ) ;
258
	while ( !IS_NULL_id ( id ) ) {
259
	    IDENTIFIER tid = find_token ( id ) ;
260
	    if ( IS_id_token ( tid ) ) {
261
		IDENTIFIER sid = DEREF_id ( id_token_alt ( tid ) ) ;
262
		ds = DEREF_dspec ( id_storage ( sid ) ) ;
263
		if ( ( ds & dspec_token ) && !( ds & dspec_template ) ) {
264
		    TOKEN tok = DEREF_tok ( id_token_sort ( tid ) ) ;
265
		    switch ( TAG_tok ( tok ) ) {
266
			case tok_exp_tag :
267
			case tok_stmt_tag :
268
			case tok_nat_tag :
269
			case tok_snat_tag :
270
			case tok_func_tag :
271
			case tok_proc_tag : {
272
			    /* These are in the macro namespace */
273
			    if ( used ) use_id ( id, 0 ) ;
274
			    token_macro = id ;
275
			    ds = DEREF_dspec ( id_storage ( tid ) ) ;
276
			    if ( ds & ( dspec_pure | dspec_defn ) ) {
277
				return ( PP_TOKEN | PP_TRUE ) ;
278
			    }
279
			    return ( PP_TOKEN | PP_FALSE ) ;
280
			}
281
		    }
282
		}
283
	    }
284
	    if ( !IS_id_function_etc ( id ) ) break ;
285
	    id = DEREF_id ( id_function_etc_over ( id ) ) ;
286
	}
287
    }
288
    return ( PP_FALSE ) ;
289
}
290
 
291
 
292
/*
293
    TARGET DEPENDENT CONDITION
294
 
295
    Any target dependent conditional compilation expressions encountered
296
    are stored in this variable.
297
*/
298
 
299
EXP crt_hash_if_exp = NULL_exp ;
300
 
301
 
302
/*
303
    PATCH PREPROCESSING DIRECTIVE INTO PREPROCESSOR OUTPUT
304
 
305
    This routine is used to patch the preprocessing directive given by
306
    the preprocessing tokens p into the main preprocessor output.  It is
307
    used to preserve target dependent conditionals and other directives
308
    which need to be passed through to the output.
309
*/
310
 
311
void patch_preproc_dir
312
    PROTO_N ( ( p ) )
313
    PROTO_T ( PPTOKEN *p )
314
{
315
    if ( p ) {
316
	PPTOKEN *q = p ;
317
	while ( q->next && q->next->tok != lex_newline ) q = q->next ;
318
	free_tok_list ( q->next ) ;
319
	q->next = crt_token->next ;
320
	crt_token->next = p ;
321
	p->pp_space = WHITE_SPACE ;
322
    }
323
    return ;
324
}
325
 
326
 
327
/*
328
    READ AN EXPRESSION COMPILATION CONDITION
329
 
330
    This routine reads the constant expression following a '#if' or '#elif'
331
    preprocessing directive.  It returns a value indicating whether the
332
    expression is zero or nonzero.  The argument act is false to indicate
333
    that the directive is being skipped.  The expression consists of all
334
    the preprocessing tokens in the rest of the directive with any
335
    defined operations suitably expanded.  This is then macro expanded
336
    and finally has any remaining identifiers replaced by 0.  All the
337
    parsing is done using this list of tokens - no other tokens are read
338
    from the input file (the newline appended by read_line ensures that
339
    the parser doesn't spill off the end).
340
*/
341
 
342
static unsigned read_if_exp
343
    PROTO_N ( ( act, dir ) )
344
    PROTO_T ( int act X int dir )
345
{
346
    EXP e = NULL_exp ;
347
    unsigned cond = PP_SKIP ;
348
    if ( act ) {
349
	/* Read the rest of the line */
350
	PARSE_STATE ps ;
351
	HASHID def = KEYWORD ( lex_defined ) ;
352
	PPTOKEN *p = read_line ( lex_ignore_token, lex_newline ) ;
353
	PPTOKEN *q = p ;
354
 
355
	/* Scan line for defined operations and assertions */
356
	while ( q != NULL ) {
357
	    int t = q->tok ;
358
 
359
	    if ( t == lex_identifier &&
360
		 EQ_hashid ( q->pp_data.id.hash, def ) ) {
361
		/* Deal with 'defined' */
362
		PPTOKEN *r = q->next ;
363
		/* Because of final newline don't need to check r != NULL */
364
		t = r->tok ;
365
		if ( t == lex_identifier ) {
366
		    /* Operation of the form 'defined id' */
367
		    HASHID macro = r->pp_data.id.hash ;
368
		    unsigned c = check_macro ( macro, 1 ) ;
369
		    c &= PP_COND_MASK ;
370
		    if ( c == PP_UNRESOLVED ) {
371
			q->tok = lex_defined ;
372
			cond = PP_UNRESOLVED ;
373
		    } else {
374
			q->tok = lex_integer_Hlit ;
375
			q->pp_data.text = ustrlit ( c ? "1" : "0" ) ;
376
			q->next = r->next ;
377
			r->next = NULL ;
378
			free_tok_list ( r ) ;
379
		    }
380
 
381
		} else if ( t == lex_open_Hround &&
382
			    r->next->tok == lex_identifier &&
383
			    r->next->next->tok == lex_close_Hround ) {
384
		    /* Operation of the form 'defined ( id )' */
385
		    HASHID macro = r->next->pp_data.id.hash ;
386
		    unsigned c = check_macro ( macro, 1 ) ;
387
		    c &= PP_COND_MASK ;
388
		    if ( c == PP_UNRESOLVED ) {
389
			q->tok = lex_defined ;
390
			cond = PP_UNRESOLVED ;
391
		    } else {
392
			q->tok = lex_integer_Hlit ;
393
			q->pp_data.text = ustrlit ( c ? "1" : "0" ) ;
394
			q->next = r->next->next->next ;
395
			r->next->next->next = NULL ;
396
			free_tok_list ( r ) ;
397
		    }
398
 
399
		} else {
400
		    /* Badly formed 'defined' operation */
401
		    report ( preproc_loc, ERR_cpp_cond_def_id () ) ;
402
		}
403
 
404
	    } else if ( ( t == lex_hash_H1 || t == lex_hash_H2 ) &&
405
			q->next->tok == lex_identifier ) {
406
		/* Deal with '#predicate' */
407
		CONST char *c = "0" ;
408
		PPTOKEN *r = q->next ;
409
		HASHID pred = r->pp_data.id.hash ;
410
		if ( t == lex_hash_H2 ) IGNORE get_digraph ( t ) ;
411
		if ( r->next->tok == lex_open_Hround ) {
412
		    /* Check for a particular predicate */
413
		    PPTOKEN *s = r->next->next ;
414
		    q->next = skip_predicate ( &s, dir ) ;
415
		    if ( check_assert ( pred, s, 0 ) ) c = "1" ;
416
		} else {
417
		    /* Check for any predicate */
418
		    if ( check_assert ( pred, r, 1 ) ) c = "1" ;
419
		    q->next = r->next ;
420
		    r->next = NULL ;
421
		}
422
		free_tok_list ( r ) ;
423
		q->tok = lex_integer_Hlit ;
424
		q->pp_data.text = ustrlit ( c ) ;
425
	    }
426
	    q = q->next ;
427
	}
428
 
429
	/* Macro expand the line */
430
	q = expand_tok_list ( p ) ;
431
	free_tok_list ( p ) ;
432
	p = q ;
433
 
434
	/* Check for any remaining identifiers */
435
	while ( q != NULL ) {
436
	    if ( q->tok == lex_identifier ) {
437
		HASHID nm = q->pp_data.id.hash ;
438
		IDENTIFIER id = DEREF_id ( hashid_id ( nm ) ) ;
439
		unsigned tag = TAG_id ( id ) ;
440
		if ( tag == id_obj_macro_tag || tag == id_func_macro_tag ) {
441
		    /* Allow for unexpanded macros */
442
		    id = DEREF_id ( id_alias ( id ) ) ;
443
		    tag = TAG_id ( id ) ;
444
		}
445
		if ( tag == id_keyword_tag ) {
446
		    int u = ( int ) DEREF_ulong ( id_no ( id ) ) ;
447
		    if ( u == lex_true || u == lex_false ) {
448
			/* Preserve boolean literals */
449
			tag = id_iso_keyword_tag ;
450
		    }
451
		}
452
		if ( tag == id_iso_keyword_tag ) {
453
		    /* Allow for ISO keywords */
454
		    int u = ( int ) DEREF_ulong ( id_no ( id ) ) ;
455
		    int v = primary_form ( u ) ;
456
		    if ( v != u ) {
457
			ERROR err = ERR_lex_digraph_iso ( nm, v ) ;
458
			report ( preproc_loc, err ) ;
459
		    }
460
		    q->tok = v ;
461
		} else {
462
		    unsigned c = check_macro ( nm, 0 ) ;
463
		    if ( c & PP_TOKEN ) {
464
			/* Preserve token identifiers */
465
			c &= PP_COND_MASK ;
466
			if ( c == PP_UNRESOLVED ) {
467
			    cond = PP_UNRESOLVED ;
468
			}
469
		    } else {
470
			/* Replace other identifiers by 0 */
471
			ERROR err ;
472
			if ( EQ_hashid ( nm, def ) ) {
473
			    /* Shouldn't have defined */
474
			    err = ERR_cpp_cond_def_replace () ;
475
			    if ( !IS_NULL_err ( err ) ) {
476
				report ( preproc_loc, err ) ;
477
			    }
478
			}
479
			/* QUERY: what about true and false? */
480
			err = ERR_cpp_cond_zero ( nm ) ;
481
			if ( !IS_NULL_err ( err ) ) {
482
			    report ( preproc_loc, err ) ;
483
			}
484
			q->tok = lex_integer_Hlit ;
485
			q->pp_data.text = ustrlit ( "0" ) ;
486
		    }
487
		}
488
	    }
489
	    q = q->next ;
490
	}
491
 
492
	/* Parse the line for a constant expression */
493
	save_state ( &ps, 0 ) ;
494
	init_parser ( p ) ;
495
	in_hash_if_exp++ ;
496
	crt_loc = preproc_loc ;
497
	crt_line_changed = 1 ;
498
	ADVANCE_LEXER ;
499
	if ( cond == PP_UNRESOLVED ) {
500
	    /* Unresolved tokens when preprocessing */
501
	    ASSERT ( preproc_only ) ;
502
	    /* EMPTY */
503
	} else {
504
	    /* Parse condition */
505
	    cond = PP_FALSE ;
506
	    parse_nat ( &e ) ;
507
	    if ( crt_lex_token != lex_newline && !have_syntax_error ) {
508
		/* Should have reached the end of the line */
509
		ERROR err = ERR_lex_parse ( crt_token ) ;
510
		err = concat_error ( err, ERR_cpp_end ( dir ) ) ;
511
		report ( preproc_loc, err ) ;
512
	    }
513
	}
514
	restore_state ( &ps ) ;
515
 
516
	/* Check the result expression */
517
	if ( !IS_NULL_exp ( e ) ) {
518
	    /* Evaluate the expression */
519
	    ERROR err = NULL_err ;
520
	    IGNORE make_nat_exp ( e, &err ) ;
521
	    e = convert_boolean ( e, exp_paren_tag, &err ) ;
522
	    if ( !IS_NULL_err ( err ) ) {
523
		err = concat_error ( err, ERR_cpp_cond_if_const ( dir ) ) ;
524
		report ( preproc_loc, err ) ;
525
		cond = PP_FALSE ;
526
	    } else {
527
		unsigned b = eval_const_cond ( e ) ;
528
		if ( b == BOOL_TRUE ) {
529
		    cond = PP_TRUE ;
530
		} else if ( b == BOOL_FALSE ) {
531
		    cond = PP_FALSE ;
532
		} else {
533
		    cond = PP_UNRESOLVED ;
534
		}
535
	    }
536
	}
537
 
538
	/* Restore the parser */
539
	p = restore_parser () ;
540
	if ( cond == PP_UNRESOLVED ) {
541
	    /* Save target dependent conditions */
542
	    if ( preproc_only ) {
543
		/* Patch crt_token with tokens comprising condition */
544
		p = clean_tok_list ( p ) ;
545
		patch_preproc_dir ( p ) ;
546
		p = NULL ;
547
	    } else {
548
		/* Store condition in crt_hash_if_exp */
549
		report ( preproc_loc, ERR_cpp_cond_if_ti ( dir ) ) ;
550
		crt_hash_if_exp = e ;
551
	    }
552
	}
553
	free_tok_list ( p ) ;
554
	in_hash_if_exp-- ;
555
    }
556
    if ( in_preproc_dir ) IGNORE skip_to_end () ;
557
    return ( cond ) ;
558
}
559
 
560
 
561
/*
562
    READ A DEFINED COMPILATION CONDITION
563
 
564
    This routine reads the macro identifier following a '#ifdef' or
565
    '#ifndef' preprocessing directive.  It returns a value indicating
566
    whether the macro is defined or not.  The argument act is false to
567
    indicate that the directive is being skipped, prev is as in
568
    read_preproc_dir.
569
*/
570
 
571
static unsigned read_if_def
572
    PROTO_N ( ( act, dir, prev ) )
573
    PROTO_T ( int act X int dir X int prev )
574
{
575
    unsigned cond ;
576
    if ( act ) {
577
	int t = read_token () ;
578
	update_column () ;
579
	if ( in_preproc_dir ) preproc_loc = crt_loc ;
580
	if ( t == lex_identifier ) {
581
	    HASHID macro = token_hashid ;
582
	    cond = check_macro ( macro, 1 ) ;
583
	    cond &= PP_COND_MASK ;
584
	    if ( prev == lex_included ) {
585
		/* Protection macro begins '#ifndef macro' */
586
		protection_macro ( macro, prev, dir ) ;
587
	    }
588
	    if ( in_preproc_dir && skip_to_end () ) {
589
		report ( preproc_loc, ERR_cpp_end ( dir ) ) ;
590
	    }
591
	} else {
592
	    report ( preproc_loc, ERR_cpp_cond_ifdef_id ( dir ) ) ;
593
	    cond = PP_FALSE ;
594
	}
595
    } else {
596
	cond = PP_SKIP ;
597
    }
598
    if ( in_preproc_dir ) IGNORE skip_to_end () ;
599
    return ( cond ) ;
600
}
601
 
602
 
603
/*
604
    DEAL WITH CONDITIONAL COMPILATIONS
605
 
606
    This routine deals with the various conditional compilation preprocessing
607
    directives.  dir gives the directive identifier and c indicates the
608
    associated condition.  The skipping of unused code is incorporated into
609
    this routine.  The routine returns lex_ignore_token for simple '#if' and
610
    '#elif' directives, lex_end_condition for simple '#else' and '#endif'
611
    directives, and one of the values lex_hash_Hif, lex_hash_Helif,
612
    lex_hash_Helse and lex_hash_Hendif for target dependent conditions.
613
*/
614
 
615
static int read_if
616
    PROTO_N ( ( dir, c, prev ) )
617
    PROTO_T ( int dir X unsigned c X int prev )
618
{
619
    unsigned cond = c ;
620
    int ret = lex_ignore_token ;
621
 
622
    if ( dir == lex_if || dir == lex_ifdef || dir == lex_ifndef ) {
623
	/* Deal with '#if', '#ifdef' and '#ifndef' */
624
	if ( cond == PP_UNRESOLVED ) ret = lex_hash_Hif ;
625
	if ( prev != lex_included && preproc_depth == 0 ) {
626
	    /* Can't have second '#if' in protection macro */
627
	    protection_macro ( NULL_hashid, lex_ignore_token, dir ) ;
628
	}
629
	PUSH_unsigned ( cond, preproc_stack ) ;
630
	PUSH_loc ( preproc_loc, loc_stack ) ;
631
	IGNORE incr_value ( OPT_VAL_hash_if_depth ) ;
632
	preproc_depth++ ;
633
 
634
    } else {
635
	/* Get current condition for other directives */
636
	LOCATION loc ;
637
	unsigned crt_cond ;
638
	POP_unsigned ( cond, preproc_stack ) ;
639
	decr_value ( OPT_VAL_hash_if_depth ) ;
640
	preproc_depth-- ;
641
	/* Don't pop location yet */
642
	if ( cond == PP_END ) {
643
	    /* No matching '#if' */
644
	    ERROR err = ERR_cpp_cond_if_match ( dir, lex_if ) ;
645
	    report ( preproc_loc, err ) ;
646
	    PUSH_unsigned ( cond, preproc_stack ) ;
647
	    PUSH_loc ( preproc_loc, loc_stack ) ;
648
	    IGNORE incr_value ( OPT_VAL_hash_if_depth ) ;
649
	    preproc_depth++ ;
650
	    cond = c ;
651
	}
652
	crt_cond = ( cond & PP_COND_MASK ) ;
653
	ret = lex_end_condition ;
654
 
655
	if ( dir == lex_endif ) {
656
	    /* Deal with '#endif' */
657
	    if ( crt_cond == PP_UNRESOLVED ) {
658
		ret = lex_hash_Hendif ;
659
		cond = PP_TRUE ;
660
	    } else if ( crt_cond == PP_SKIP ) {
661
		cond = PP_SKIP ;
662
	    } else {
663
		cond = PP_TRUE ;
664
	    }
665
	    POP_loc ( loc, loc_stack ) ;
666
	    UNUSED ( loc ) ;
667
 
668
	} else if ( dir == lex_else ) {
669
	    /* Deal with '#else' */
670
	    PTR ( LOCATION ) ploc ;
671
	    ploc = HEAD_list ( LIST_stack ( loc_stack ) ) ;
672
	    if ( cond & PP_HAVE_ELSE ) {
673
		/* Duplicate '#else' directives */
674
		ERROR err = ERR_cpp_cond_else_dup ( dir, dir, ploc ) ;
675
		report ( preproc_loc, err ) ;
676
	    }
677
	    if ( crt_cond == PP_UNRESOLVED ) ret = lex_hash_Helse ;
678
	    cond = ( negate_cond ( crt_cond ) | PP_HAVE_ELSE ) ;
679
	    PUSH_unsigned ( cond, preproc_stack ) ;
680
	    COPY_loc ( ploc, preproc_loc ) ;
681
	    if ( preproc_depth == 0 ) {
682
		/* Can't have '#else' in protection macro */
683
		protection_macro ( NULL_hashid, lex_ignore_token, dir ) ;
684
	    }
685
	    IGNORE incr_value ( OPT_VAL_hash_if_depth ) ;
686
	    preproc_depth++ ;
687
 
688
	} else {
689
	    /* Deal with '#elif' (fairly tricky) */
690
	    unsigned new_cond ;
691
	    PTR ( LOCATION ) ploc ;
692
	    ploc = HEAD_list ( LIST_stack ( loc_stack ) ) ;
693
	    if ( cond & PP_HAVE_ELSE ) {
694
		/* '#elif' after '#else' */
695
		ERROR err = ERR_cpp_cond_else_dup ( dir, lex_else, ploc ) ;
696
		report ( preproc_loc, err ) ;
697
	    }
698
	    if ( crt_cond == PP_TRUE || crt_cond == PP_PAST ) {
699
		/* A previous '#if' or '#elif' was true */
700
		ret = lex_ignore_token ;
701
		IGNORE read_if_exp ( 0, dir ) ;
702
		c = PP_PAST ;
703
		new_cond = ( c | PP_HAVE_ELIF ) ;
704
	    } else if ( crt_cond == PP_FALSE ) {
705
		/* All previous '#if's and '#elif's were false */
706
		c = read_if_exp ( 1, dir ) ;
707
		if ( c == PP_UNRESOLVED ) ret = lex_hash_Hif ;
708
		new_cond = ( c | PP_HAVE_ELIF ) ;
709
	    } else if ( crt_cond == PP_UNRESOLVED ) {
710
		/* Unresolved existing condition */
711
		c = read_if_exp ( 1, dir ) ;
712
		if ( c == PP_FALSE ) {
713
		    /* Overall condition is still unresolved */
714
		    ret = lex_ignore_token ;
715
		    new_cond = ( crt_cond | PP_HAVE_ELIF ) ;
716
		} else if ( c == PP_TRUE ) {
717
		    /* This terminates the conditional */
718
		    ret = lex_hash_Hendif ;
719
		    new_cond = ( c | PP_HAVE_ELIF ) ;
720
		} else {
721
		    /* A second unresolved condition */
722
		    ret = lex_hash_Helif ;
723
		    new_cond = ( c | PP_HAVE_ELIF ) ;
724
		}
725
	    } else {
726
		/* Skip this directive */
727
		ret = lex_ignore_token ;
728
		c = read_if_exp ( 0, dir ) ;
729
		new_cond = ( c | PP_HAVE_ELIF ) ;
730
	    }
731
	    PUSH_unsigned ( new_cond, preproc_stack ) ;
732
	    COPY_loc ( ploc, preproc_loc ) ;
733
	    if ( preproc_depth == 0 ) {
734
		/* Can't have '#elif' in protection macro */
735
		protection_macro ( NULL_hashid, lex_ignore_token, dir ) ;
736
	    }
737
	    IGNORE incr_value ( OPT_VAL_hash_if_depth ) ;
738
	    preproc_depth++ ;
739
	    cond = c ;
740
	}
741
    }
742
    ASSERT ( !in_preproc_dir ) ;
743
 
744
    /* Step over any unused code */
745
    cond &= PP_COND_MASK ;
746
    if ( cond == PP_FALSE || cond == PP_PAST || cond == PP_SKIP ) {
747
	for ( ; ; ) {
748
	    int t ;
749
	    unsigned long sp = skip_white ( 1 ) ;
750
	    in_preproc_dir = 1 ;
751
	    t = read_token () ;
752
	    update_column () ;
753
	    if ( in_preproc_dir ) preproc_loc = crt_loc ;
754
	    if ( t == lex_hash_H2 ) t = get_digraph ( t ) ;
755
	    if ( t == lex_hash_H1 ) {
756
		/* Scan any nested preprocessing directives */
757
		int p ;
758
		unsigned long sp2 = skip_white ( 0 ) ;
759
		update_column () ;
760
		p = read_preproc_dir ( 0, lex_ignore_token ) ;
761
		switch ( p ) {
762
		    case lex_hash_Hif :
763
		    case lex_hash_Helif :
764
		    case lex_hash_Helse :
765
		    case lex_hash_Hendif :
766
		    case lex_end_condition : {
767
			/* These terminate the current condition */
768
			if ( sp & ( WHITE_SPACE | WHITE_ESC_NEWLINE ) ) {
769
			    report ( preproc_loc, ERR_cpp_indent () ) ;
770
			}
771
			if ( sp2 & ( WHITE_SPACE | WHITE_ESC_NEWLINE ) ) {
772
			    report ( preproc_loc, ERR_cpp_indent_dir () ) ;
773
			}
774
			in_preproc_dir = 0 ;
775
			return ( p ) ;
776
		    }
777
		}
778
	    } else if ( t == lex_eof ) {
779
		if ( sp & ( WHITE_SPACE | WHITE_ESC_NEWLINE ) ) {
780
		    report ( crt_loc, ERR_lex_phases_eof () ) ;
781
		}
782
		break ;
783
	    } else {
784
		if ( in_preproc_dir ) IGNORE skip_to_end () ;
785
	    }
786
	}
787
    }
788
    in_preproc_dir = 0 ;
789
    return ( ret ) ;
790
}
791
 
792
 
793
/*
794
    PATCH TARGET DEPENDENT CONDITIONALS
795
 
796
    Any list of statements in a target dependent conditional are treated
797
    as if they comprised a compound statement.  In particular any variables
798
    declared within the conditional are only in scope inside that condition.
799
    The neatest way to do this is for the preprocessor to patch the necessary
800
    open and close braces into the parser input.  This is the purpose of
801
    this routine.
802
*/
803
 
804
int patch_cond
805
    PROTO_N ( ( t, dir ) )
806
    PROTO_T ( int t X int dir )
807
{
808
    HASHID nm ;
809
    PPTOKEN *p ;
810
    IDENTIFIER id ;
811
 
812
    /* Compilation action */
813
    if ( !preproc_only ) {
814
	switch ( t ) {
815
	    case lex_hash_Hif : {
816
		/* Create '#if {' */
817
		p = patch_tokens ( 1 ) ;
818
		p->tok = lex_open_Hbrace_H1 ;
819
		break ;
820
	    }
821
	    case lex_hash_Helif :
822
	    case lex_hash_Helse : {
823
		/* Create '} #elif {' and '} #else {' */
824
		p = patch_tokens ( 2 ) ;
825
		p->tok = t ;
826
		token_parts ( t, p ) ;
827
		p->next->tok = lex_open_Hbrace_H1 ;
828
		t = lex_close_Hbrace_H1 ;
829
		break ;
830
	    }
831
	    case lex_hash_Hendif : {
832
		/* Create '} #endif' */
833
		p = patch_tokens ( 1 ) ;
834
		p->tok = t ;
835
		t = lex_close_Hbrace_H1 ;
836
		break ;
837
	    }
838
	}
839
	return ( t ) ;
840
    }
841
 
842
    /* Preprocessing action */
843
    id = token_macro ;
844
    if ( IS_NULL_id ( id ) ) return ( t ) ;
845
    nm = DEREF_hashid ( id_name ( id ) ) ;
846
    switch ( t ) {
847
 
848
	case lex_hash_Hif : {
849
	    if ( dir == lex_ifdef ) {
850
		/* Create '#if defined x' */
851
		p = patch_tokens ( 2 ) ;
852
		p->tok = lex_identifier ,
853
		p->pp_data.id.hash = KEYWORD ( lex_defined ) ;
854
		p->next->tok = lex_identifier ,
855
		p->next->pp_data.id.hash = nm ;
856
		p->next->pp_data.id.use = id ;
857
	    } else if ( dir == lex_ifndef ) {
858
		/* Create '#if !defined x' */
859
		p = patch_tokens ( 3 ) ;
860
		p->tok = lex_not_H1 ;
861
		p->next->tok = lex_identifier ,
862
		p->next->pp_data.id.hash = KEYWORD ( lex_defined ) ;
863
		p->next->pp_space = 0 ;
864
		p->next->next->tok = lex_identifier ,
865
		p->next->next->pp_data.id.hash = nm ;
866
		p->next->next->pp_data.id.use = id ;
867
	    }
868
	    break ;
869
	}
870
 
871
	case lex_hash_Hop : {
872
	    /* Create '#define x ...' or '#undef x' */
873
	    if ( dir == lex_define ) {
874
		/* Patch in macro definition */
875
		PPTOKEN *q = NULL ;
876
		unsigned tag = TAG_id ( id ) ;
877
		if ( tag == id_obj_macro_tag ) {
878
		    q = DEREF_pptok ( id_obj_macro_defn ( id ) ) ;
879
		} else if ( tag == id_func_macro_tag ) {
880
		    q = DEREF_pptok ( id_func_macro_defn ( id ) ) ;
881
		}
882
		q = expand_tok_list ( q ) ;
883
		q = clean_tok_list ( q ) ;
884
		patch_preproc_dir ( q ) ;
885
		if ( tag == id_func_macro_tag ) {
886
		    unsigned n ;
887
		    LIST ( HASHID ) pars ;
888
		    pars = DEREF_list ( id_func_macro_params ( id ) ) ;
889
		    n = DEREF_unsigned ( id_func_macro_no_params ( id ) ) ;
890
		    p = patch_tokens ( ( int ) ( 2 * n + 2 ) ) ;
891
		    p->tok = lex_open_Hround ;
892
		    p->pp_space = 0 ;
893
		    p->next->tok = lex_close_Hround ;
894
		    p->next->pp_space = 0 ;
895
		    while ( !IS_NULL_list ( pars ) ) {
896
			HASHID par = DEREF_hashid ( HEAD_list ( pars ) ) ;
897
			pars = TAIL_list ( pars ) ;
898
			p = p->next ;
899
			p->tok = lex_identifier ;
900
			p->pp_data.id.hash = par ;
901
			p->pp_space = WHITE_SPACE ;
902
			p = p->next ;
903
			if ( IS_NULL_list ( pars ) ) {
904
			    p->tok = lex_close_Hround ;
905
			    p->pp_space = WHITE_SPACE ;
906
			} else {
907
			    p->tok = lex_comma ;
908
			    p->pp_space = 0 ;
909
			}
910
		    }
911
		}
912
	    }
913
	    p = patch_tokens ( 2 ) ;
914
	    p->tok = lex_identifier ;
915
	    p->pp_data.id.hash = KEYWORD ( dir ) ;
916
	    p->pp_space = 0 ;
917
	    p->next->tok = lex_identifier ,
918
	    p->next->pp_data.id.hash = nm ;
919
	    p->next->pp_data.id.use = id ;
920
	    break ;
921
	}
922
    }
923
    return ( t ) ;
924
}
925
 
926
 
927
/*
928
    READ AN INCLUDE DIRECTIVE
929
 
930
    This routine processes a '#include' or similar directive.  This consists
931
    of just a header name or a sequence of tokens which expand to a header
932
    name.  If act is true then the actual inclusion is initialised.
933
    The name of the preprocessing directive, dir, is passed in for the
934
    purposes of error reporting.  The routine returns lex_included to
935
    indicate that control has passed to the new file.
936
*/
937
 
938
int read_include
939
    PROTO_N ( ( act, dir ) )
940
    PROTO_T ( int act X int dir )
941
{
942
    int ret = lex_ignore_token ;
943
    if ( act ) {
944
	string s ;
945
	character c ;
946
	int end = 0 ;
947
	int next = 0 ;
948
	int legal = 1 ;
949
	int import = 0 ;
950
	character quote = 0 ;
951
 
952
	/* Look ahead for start of header name */
953
	if ( dir == lex_import ) import = 1 ;
954
	if ( dir == lex_include_Hnext ) next = 1 ;
955
	IGNORE skip_white ( 0 ) ;
956
	if ( peek_char ( char_less, &legal ) ) {
957
	    quote = char_greater ;
958
	} else if ( peek_char ( char_quote, &legal ) ) {
959
	    quote = char_quote ;
960
	} else if ( dir == lex_pragma ) {
961
	    if ( peek_char ( char_open_square, &legal ) ) {
962
		quote = char_close_square ;
963
		next = 1 ;
964
	    }
965
	}
966
	update_column () ;
967
 
968
	if ( quote ) {
969
	    /* Read simple header name */
970
	    int e = read_string ( ( int ) quote, 0 ) ;
971
	    if ( e != lex_eof ) {
972
		if ( in_preproc_dir ) end = skip_to_end () ;
973
	    }
974
	    s = token_buff.start ;
975
	} else {
976
	    /* Expand complex header name */
977
	    PPTOKEN *p = read_line ( lex_ignore_token, lex_ignore_token ) ;
978
	    PPTOKEN *q = expand_tok_list ( p ) ;
979
	    IGNORE quote_tok_list ( q, 0, char_quote ) ;
980
	    s = token_buff.start ;
981
 
982
	    /* Check first character */
983
	    c = s [0] ;
984
	    if ( c == char_less ) {
985
		quote = char_greater ;
986
	    } else if ( c == char_quote ) {
987
		quote = char_quote ;
988
	    } else if ( dir == lex_pragma && c == char_open_square ) {
989
		quote = char_close_square ;
990
		next = 1 ;
991
	    } else {
992
		report ( preproc_loc, ERR_cpp_include_bad () ) ;
993
		act = 0 ;
994
	    }
995
 
996
	    /* Scan header name */
997
	    if ( quote ) {
998
		string t = ++s ;
999
		for ( ; ; ) {
1000
		    if ( *t == quote ) {
1001
			*t = 0 ;
1002
			if ( t + 1 != token_buff.posn ) end = 1 ;
1003
			break ;
1004
		    }
1005
		    if ( t == token_buff.posn ) {
1006
			/* End of buffer reached */
1007
			report ( preproc_loc, ERR_cpp_include_incompl () ) ;
1008
			break ;
1009
		    }
1010
		    t++ ;
1011
		}
1012
	    }
1013
	    free_tok_list ( p ) ;
1014
	    free_tok_list ( q ) ;
1015
	}
1016
	if ( end ) report ( preproc_loc, ERR_cpp_end ( dir ) ) ;
1017
	in_preproc_dir = 0 ;
1018
	if ( act ) {
1019
	    /* Check header name */
1020
	    string t = s ;
1021
	    while ( c = *( t++ ), c != 0 ) {
1022
		if ( c == char_quote ||
1023
		     c == char_single_quote || c == char_backslash ||
1024
		     ( c == char_slash && *t == char_asterix ) ||
1025
		     ( c == char_slash && *t == char_slash ) ) {
1026
		    report ( preproc_loc, ERR_cpp_include_undef ( s ) ) ;
1027
		    break ;
1028
		}
1029
	    }
1030
	    if ( start_include ( s, ( int ) quote, import, next ) ) {
1031
		/* Control passed to new file */
1032
		ret = lex_included ;
1033
	    }
1034
	}
1035
    } else {
1036
	/* Ignore rest of line */
1037
	if ( in_preproc_dir ) IGNORE skip_to_end () ;
1038
    }
1039
    return ( ret ) ;
1040
}
1041
 
1042
 
1043
/*
1044
    CHECK THAT TWO PREPROCESSING TOKENS ARE EQUAL
1045
 
1046
    This routine checks whether the lists of preprocessing tokens p and q
1047
    are identical.  It returns 2 if they are equal including preceeding
1048
    white spaces, 1 if they are otherwise equal, and 0 otherwise.
1049
*/
1050
 
1051
static int eq_pptok
1052
    PROTO_N ( ( p, q ) )
1053
    PROTO_T ( PPTOKEN *p X PPTOKEN *q )
1054
{
1055
    int eq = 2 ;
1056
    while ( p && q ) {
1057
	int t1 = p->tok ;
1058
	int t2 = q->tok ;
1059
	if ( t1 != t2 ) return ( 0 ) ;
1060
	if ( p->pp_space != q->pp_space ) eq = 1 ;
1061
	switch ( t1 ) {
1062
	    case lex_identifier : {
1063
		/* Check identifiers */
1064
		HASHID n1 = p->pp_data.id.hash ;
1065
		HASHID n2 = q->pp_data.id.hash ;
1066
		if ( !EQ_hashid ( n1, n2 ) ) return ( 0 ) ;
1067
		break ;
1068
	    }
1069
	    case lex_integer_Hlit : {
1070
		/* Check integer and floating-point literals */
1071
		string s1 = p->pp_data.text ;
1072
		string s2 = q->pp_data.text ;
1073
		if ( !ustreq ( s1, s2 ) ) return ( 0 ) ;
1074
		break ;
1075
	    }
1076
	    case lex_char_Hlit :
1077
	    case lex_string_Hlit :
1078
	    case lex_wchar_Hlit :
1079
	    case lex_wstring_Hlit : {
1080
		/* Check string and characters literals */
1081
		string s1 = p->pp_data.str.start ;
1082
		string s2 = q->pp_data.str.start ;
1083
		gen_size n1 = ( gen_size ) ( p->pp_data.str.end - s1 ) ;
1084
		gen_size n2 = ( gen_size ) ( q->pp_data.str.end - s2 ) ;
1085
		if ( n1 != n2 ) return ( 0 ) ;
1086
		if ( xumemcmp ( s1, s2, n1 ) != 0 ) return ( 0 ) ;
1087
		break ;
1088
	    }
1089
	    case lex_unknown : {
1090
		/* Check unknown characters */
1091
		string s1 = p->pp_data.buff ;
1092
		string s2 = q->pp_data.buff ;
1093
		gen_size n1 = MULTI_WIDTH ;
1094
		if ( xumemcmp ( s1, s2, n1 ) != 0 ) return ( 0 ) ;
1095
		break ;
1096
	    }
1097
	    case lex_macro_Harg : {
1098
		/* Check macro parameter applications */
1099
		unsigned long m1 = p->pp_data.par.no ;
1100
		unsigned long m2 = q->pp_data.par.no ;
1101
		if ( m1 != m2 ) return ( 0 ) ;
1102
		break ;
1103
	    }
1104
	}
1105
	p = p->next ;
1106
	q = q->next ;
1107
    }
1108
    if ( p || q ) return ( 0 ) ;
1109
    return ( eq ) ;
1110
}
1111
 
1112
 
1113
/*
1114
    CHECK CONSISTENCY OF TWO MACRO DEFINITIONS
1115
 
1116
    This routine checks that a definition of the macro given by id_new is
1117
    consistent with the previous definition, id_old.  It returns an error
1118
    message reporting on the level of consistency.
1119
*/
1120
 
1121
static ERROR check_macro_redef
1122
    PROTO_N ( ( id_new, id_old ) )
1123
    PROTO_T ( IDENTIFIER id_new X IDENTIFIER id_old )
1124
{
1125
    int defn_ok ;
1126
    int pars_ok = 1 ;
1127
    ERROR err = NULL_err ;
1128
    PTR ( LOCATION ) loc_old ;
1129
    PPTOKEN *defn_new, *defn_old ;
1130
    unsigned tag_new = TAG_id ( id_new ) ;
1131
    unsigned tag_old = TAG_id ( id_old ) ;
1132
    DECL_SPEC ds_old = DEREF_dspec ( id_storage ( id_old ) ) ;
1133
 
1134
    /* Check on old macro definition */
1135
    loc_old = id_loc ( id_old ) ;
1136
    if ( ( ds_old & dspec_builtin ) && crt_file_type == 0 ) {
1137
	/* Built-in macro redefined */
1138
	err = ERR_cpp_predef_redef ( id_old ) ;
1139
    }
1140
 
1141
    /* Macro types must agree */
1142
    if ( tag_new != tag_old ) {
1143
	ERROR e = ERR_cpp_replace_redef_bad ( id_old, loc_old ) ;
1144
	err = concat_error ( err, e ) ;
1145
	return ( err ) ;
1146
    }
1147
 
1148
    if ( tag_new == id_obj_macro_tag ) {
1149
	/* Find the definitions for object-like macros */
1150
	defn_new = DEREF_pptok ( id_obj_macro_defn ( id_new ) ) ;
1151
	defn_old = DEREF_pptok ( id_obj_macro_defn ( id_old ) ) ;
1152
 
1153
    } else {
1154
	/* Check parameter lists for function-like macros */
1155
	unsigned no_pars_new, no_pars_old ;
1156
	LIST ( HASHID ) pars_new, pars_old ;
1157
	pars_new = DEREF_list ( id_func_macro_params ( id_new ) ) ;
1158
	pars_old = DEREF_list ( id_func_macro_params ( id_old ) ) ;
1159
	no_pars_new = DEREF_unsigned ( id_func_macro_no_params ( id_new ) ) ;
1160
	no_pars_old = DEREF_unsigned ( id_func_macro_no_params ( id_old ) ) ;
1161
 
1162
	if ( no_pars_new != no_pars_old ) {
1163
	    /* Number of parameters must match */
1164
	    ERROR e = ERR_cpp_replace_redef_bad ( id_old, loc_old ) ;
1165
	    err = concat_error ( err, e ) ;
1166
	    return ( err ) ;
1167
	}
1168
 
1169
	while ( !IS_NULL_list ( pars_new ) ) {
1170
	    /* Check that parameter names match */
1171
	    HASHID p_new = DEREF_hashid ( HEAD_list ( pars_new ) ) ;
1172
	    HASHID p_old = DEREF_hashid ( HEAD_list ( pars_old ) ) ;
1173
	    if ( !EQ_hashid ( p_new, p_old ) ) {
1174
		/* Just clear pars_ok if they don't */
1175
		pars_ok = 0 ;
1176
		break ;
1177
	    }
1178
	    pars_new = TAIL_list ( pars_new ) ;
1179
	    pars_old = TAIL_list ( pars_old ) ;
1180
	}
1181
 
1182
	/* Find the definitions for function-like macros */
1183
	defn_new = DEREF_pptok ( id_func_macro_defn ( id_new ) ) ;
1184
	defn_old = DEREF_pptok ( id_func_macro_defn ( id_old ) ) ;
1185
    }
1186
 
1187
    /* Check that the definitions match */
1188
    defn_ok = eq_pptok ( defn_new, defn_old ) ;
1189
    if ( defn_ok == 0 ) {
1190
	/* Inconsistent redefinition */
1191
	ERROR e = ERR_cpp_replace_redef_bad ( id_old, loc_old ) ;
1192
	err = concat_error ( err, e ) ;
1193
	return ( err ) ;
1194
    } else if ( defn_ok == 1 ) {
1195
	/* Consistent redefinition up to white space */
1196
	ERROR e = ERR_cpp_replace_redef_space ( id_old, loc_old ) ;
1197
	e = set_severity ( e, OPT_macro_redef, -1 ) ;
1198
	err = concat_error ( err, e ) ;
1199
    }
1200
 
1201
    /* Prepare final error */
1202
    if ( pars_ok ) {
1203
	/* Consistent macro redefinition */
1204
	if ( IS_NULL_err ( err ) ) {
1205
	    err = ERR_cpp_replace_redef_ok ( id_old, loc_old ) ;
1206
	}
1207
    } else {
1208
	/* Consistent redefinition up to parameter names */
1209
	ERROR e = ERR_cpp_replace_redef_weak ( id_old, loc_old ) ;
1210
	e = set_severity ( e, OPT_macro_redef, -1 ) ;
1211
	err = concat_error ( err, e ) ;
1212
    }
1213
    return ( err ) ;
1214
}
1215
 
1216
 
1217
/*
1218
    FREE A MACRO DEFINITION
1219
 
1220
    This routine frees the macro definition given by the identifier id.
1221
    It returns the previous definition of id.
1222
*/
1223
 
1224
static IDENTIFIER free_macro_defn
1225
    PROTO_N ( ( id ) )
1226
    PROTO_T ( IDENTIFIER id )
1227
{
1228
    PPTOKEN *defn ;
1229
    IDENTIFIER prev = DEREF_id ( id_alias ( id ) ) ;
1230
    if ( IS_id_obj_macro ( id ) ) {
1231
	defn = DEREF_pptok ( id_obj_macro_defn ( id ) ) ;
1232
	COPY_pptok ( id_obj_macro_defn ( id ), NULL ) ;
1233
    } else {
1234
	defn = DEREF_pptok ( id_func_macro_defn ( id ) ) ;
1235
	COPY_pptok ( id_func_macro_defn ( id ), NULL ) ;
1236
    }
1237
    free_tok_list ( defn ) ;
1238
    return ( prev ) ;
1239
}
1240
 
1241
 
1242
/*
1243
    READ A DEFINE DIRECTIVE
1244
 
1245
    This routine processes a '#define' directive.  This consists of a macro
1246
    identifier, and optional list of macro parameters, and a list of token
1247
    comprising the macro definition.  Note that the list of parameters is
1248
    built up in the reverse order to that in which they appear in the file
1249
    (also see read_macro_args).  The routine returns true if the directive
1250
    is a macro definition.
1251
*/
1252
 
1253
static int read_define
1254
    PROTO_Z ()
1255
{
1256
    HASHID macro ;
1257
    PPTOKEN *defn ;
1258
    int legal = 1 ;
1259
    IDENTIFIER id ;
1260
    IDENTIFIER tok ;
1261
    IDENTIFIER prev ;
1262
    unsigned prev_def ;
1263
    unsigned npars = 0 ;
1264
    int object_like = 0 ;
1265
    int ret = lex_ignore_token ;
1266
    int first_tok = lex_ignore_token ;
1267
    LIST ( HASHID ) pars = NULL_list ( HASHID ) ;
1268
    OPTION preproc_strings = option ( OPT_preproc_old ) ;
1269
 
1270
    /* Read the macro identifier */
1271
    int t = read_token () ;
1272
    update_column () ;
1273
    if ( in_preproc_dir ) preproc_loc = crt_loc ;
1274
    if ( t != lex_identifier ) {
1275
	report ( preproc_loc, ERR_cpp_replace_id ( lex_define ) ) ;
1276
	return ( ret ) ;
1277
    }
1278
    macro = token_hashid ;
1279
    if ( EQ_KEYWORD ( macro, lex_defined ) ) {
1280
	/* Cannot define defined as a macro */
1281
	report ( preproc_loc, ERR_cpp_predef_bad ( macro, lex_define ) ) ;
1282
    } else {
1283
	id = DEREF_id ( hashid_id ( macro ) ) ;
1284
	if ( IS_id_keyword ( id ) && !preproc_only ) {
1285
	    /* Warn about redefining keywords */
1286
	    report ( preproc_loc, ERR_cpp_predef_keyword ( macro ) ) ;
1287
	}
1288
    }
1289
    prev_def = check_macro ( macro, 0 ) ;
1290
    tok = token_macro ;
1291
 
1292
    /* Check for macro parameters */
1293
    if ( peek_char ( char_open_round, &legal ) ) {
1294
	PPTOKEN *p ;
1295
	int err = 0 ;
1296
	int par_next = 2 ;
1297
	LIST ( HASHID ) lp ;
1298
	unsigned long par_no = 1 ;
1299
 
1300
	/* Scan through definition looking for parameters */
1301
	update_column () ;
1302
	if ( in_preproc_dir ) preproc_loc = crt_loc ;
1303
	while ( t = read_token (), t != lex_close_Hround ) {
1304
	    update_column () ;
1305
	    if ( in_preproc_dir ) preproc_loc = crt_loc ;
1306
	    if ( t == lex_identifier ) {
1307
		/* Identifiers are parameter names */
1308
		unsigned long mark ;
1309
		HASHID par = token_hashid ;
1310
		IGNORE check_macro ( par, 0 ) ;
1311
		CONS_hashid ( par, pars, pars ) ;
1312
 
1313
		/* Mark name with parameter number */
1314
		mark = DEREF_ulong ( hashid_hash ( par ) ) ;
1315
		if ( mark >= HASH_SIZE ) {
1316
		    /* Parameter already marked */
1317
		    ERROR e = ERR_cpp_replace_par_dup ( par, macro ) ;
1318
		    report ( preproc_loc, e ) ;
1319
		    mark %= HASH_SIZE ;
1320
		}
1321
		mark += HASH_SIZE * par_no ;
1322
		COPY_ulong ( hashid_hash ( par ), mark ) ;
1323
		if ( !par_next ) err = 1 ;
1324
		par_next = 0 ;
1325
		par_no++ ;
1326
	    } else if ( t == lex_comma ) {
1327
		/* Commas separate parameters */
1328
		if ( par_next ) err = 1 ;
1329
		par_next = 1 ;
1330
	    } else {
1331
		/* Anything else is an error */
1332
		first_tok = t ;
1333
		err = 1 ;
1334
		break ;
1335
	    }
1336
	}
1337
	update_column () ;
1338
	if ( in_preproc_dir ) preproc_loc = crt_loc ;
1339
	if ( err || par_next == 1 ) {
1340
	    /* Report any errors */
1341
	    report ( preproc_loc, ERR_cpp_replace_par_bad ( macro ) ) ;
1342
	}
1343
 
1344
	/* Allow for parameter expansion in strings */
1345
	if ( preproc_strings ) {
1346
	    /* This causes strings not to be recognised */
1347
	    set_char_lookup ( char_quote, char_illegal ) ;
1348
	    set_char_lookup ( char_single_quote, char_illegal ) ;
1349
	}
1350
 
1351
	/* Read the macro definition for function-like macros */
1352
	defn = read_line ( first_tok, lex_ignore_token ) ;
1353
	if ( defn ) defn->pp_space = WHITE_SPACE ;
1354
 
1355
	/* Restore string terminators */
1356
	if ( preproc_strings ) {
1357
	    set_char_lookup ( char_quote, char_quote ) ;
1358
	    set_char_lookup ( char_single_quote, char_single_quote ) ;
1359
	}
1360
 
1361
	/* Mark the macro parameters in the definition */
1362
	for ( p = defn ; p != NULL ; p = p->next ) {
1363
	    int tk = p->tok ;
1364
	    if ( tk == lex_identifier ) {
1365
		HASHID par = p->pp_data.id.hash ;
1366
		unsigned long mark = DEREF_ulong ( hashid_hash ( par ) ) ;
1367
		if ( mark >= HASH_SIZE ) {
1368
		    /* Parameters are identified by the parameter number */
1369
		    p->tok = lex_macro_Harg ;
1370
		    p->pp_data.par.hash = par ;
1371
		    p->pp_data.par.no = ( mark / HASH_SIZE ) ;
1372
		}
1373
	    }
1374
	}
1375
 
1376
	/* Check for quoted parameters */
1377
	if ( preproc_strings ) {
1378
	    defn = recognise_strings ( defn, macro, 0 ) ;
1379
	}
1380
 
1381
	/* Check for '#' operators */
1382
	for ( p = defn ; p != NULL ; p = p->next ) {
1383
	    int tk = p->tok ;
1384
	    if ( tk == lex_hash_H2 ) tk = get_digraph ( tk ) ;
1385
	    if ( tk == lex_hash_H1 ) {
1386
		/* '#' should be followed by a parameter */
1387
		if ( p->next == NULL || p->next->tok != lex_macro_Harg ) {
1388
		    report ( preproc_loc, ERR_cpp_stringize_par ( macro ) ) ;
1389
		} else {
1390
		    p->tok = lex_hash_Hop ;
1391
		}
1392
	    }
1393
	}
1394
 
1395
	/* Clear the parameter marks */
1396
	for ( lp = pars ; !IS_NULL_list ( lp ) ; lp = TAIL_list ( lp ) ) {
1397
	    HASHID par = DEREF_hashid ( HEAD_list ( lp ) ) ;
1398
	    unsigned long mark = DEREF_ulong ( hashid_hash ( par ) ) ;
1399
	    mark %= HASH_SIZE ;
1400
	    COPY_ulong ( hashid_hash ( par ), mark ) ;
1401
	    npars++ ;
1402
	}
1403
	pars = REVERSE_list ( pars ) ;
1404
 
1405
    } else {
1406
	/* Read the macro definition for object-like macros */
1407
	if ( !legal ) report ( preproc_loc, ERR_cpp_space_replace () ) ;
1408
	defn = read_line ( first_tok, lex_ignore_token ) ;
1409
	object_like = 1 ;
1410
    }
1411
 
1412
    /* Check for '##' operators */
1413
    if ( defn ) {
1414
	PPTOKEN *p ;
1415
	int tk = defn->tok ;
1416
	if ( tk == lex_hash_Hhash_H2 ) tk = get_digraph ( tk ) ;
1417
	if ( tk == lex_hash_Hhash_H1 ) {
1418
	    /* Definition can't start with '##' */
1419
	    report ( preproc_loc, ERR_cpp_concat_place ( macro ) ) ;
1420
	}
1421
	for ( p = defn->next ; p != NULL ; p = p->next ) {
1422
	    tk = p->tok ;
1423
	    if ( tk == lex_hash_Hhash_H2 ) tk = get_digraph ( tk ) ;
1424
	    if ( tk == lex_hash_Hhash_H1 ) {
1425
		if ( p->next == NULL ) {
1426
		    /* Definition can't end with '##' */
1427
		    report ( preproc_loc, ERR_cpp_concat_place ( macro ) ) ;
1428
		} else {
1429
		    p->tok = lex_hash_Hhash_Hop ;
1430
		}
1431
	    }
1432
	}
1433
    }
1434
 
1435
    /* Define the macro */
1436
    if ( !IS_NULL_exp ( crt_hash_cond ) ) {
1437
	report ( preproc_loc, ERR_cpp_cond_if_macro ( macro ) ) ;
1438
    }
1439
    prev = DEREF_id ( hashid_id ( macro ) ) ;
1440
    if ( object_like ) {
1441
	MAKE_id_obj_macro ( macro, dspec_defn, NULL_nspace, preproc_loc,
1442
			    defn, id ) ;
1443
    } else {
1444
	IGNORE check_value ( OPT_VAL_macro_pars, ( ulong ) npars ) ;
1445
	MAKE_id_func_macro ( macro, dspec_defn, NULL_nspace, preproc_loc,
1446
			     defn, pars, npars, id ) ;
1447
    }
1448
    COPY_id ( id_alias ( id ), prev ) ;
1449
    if ( prev_def & PP_TOKEN ) {
1450
	/* Allow for token definitions */
1451
	prev_def &= PP_COND_MASK ;
1452
	if ( prev_def == PP_UNRESOLVED ) {
1453
	    /* Can only happen when preprocessing */
1454
	    token_macro = id ;
1455
	    ret = lex_hash_Hop ;
1456
	} else {
1457
	    int tokdef ;
1458
	    DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
1459
	    COPY_dspec ( id_storage ( id ), ( ds | dspec_temp ) ) ;
1460
	    tokdef = define_token_macro ( tok, id ) ;
1461
	    COPY_dspec ( id_storage ( id ), ds ) ;
1462
	    if ( tokdef ) {
1463
		IGNORE free_macro_defn ( id ) ;
1464
		no_declarations++ ;
1465
		return ( ret ) ;
1466
	    }
1467
	    prev_def = PP_FALSE ;
1468
	}
1469
    }
1470
    COPY_id ( hashid_id ( macro ), id ) ;
1471
    if ( do_macro ) {
1472
	/* Dump macro definition using current namespace */
1473
	COPY_nspace ( id_parent ( id ), crt_namespace ) ;
1474
	dump_declare ( id, &preproc_loc, 1 ) ;
1475
	COPY_nspace ( id_parent ( id ), NULL_nspace ) ;
1476
    }
1477
 
1478
    /* Check consistency of previous definition */
1479
    if ( prev_def == PP_TRUE ) {
1480
	ERROR err ;
1481
	if ( option ( OPT_macro_nest ) == OPTION_DISALLOW ) {
1482
	    err = check_macro_redef ( id, prev ) ;
1483
	    prev = free_macro_defn ( prev ) ;
1484
	} else {
1485
	    PTR ( LOCATION ) loc = id_loc ( prev ) ;
1486
	    err = ERR_cpp_replace_redef_nest ( prev, loc ) ;
1487
	}
1488
	if ( !IS_NULL_err ( err ) ) report ( preproc_loc, err ) ;
1489
	COPY_id ( id_alias ( id ), prev ) ;
1490
    } else {
1491
	IGNORE incr_value ( OPT_VAL_macro_ids ) ;
1492
    }
1493
    return ( ret ) ;
1494
}
1495
 
1496
 
1497
/*
1498
    READ AN UNDEFINE DIRECTIVE
1499
 
1500
    This routine processes a '#undef' directive.  This just consists of a
1501
    macro identifier.  The routine returns true if the macro represents
1502
    a token.
1503
*/
1504
 
1505
static int read_undef
1506
    PROTO_Z ()
1507
{
1508
    /* Read the macro identifier */
1509
    unsigned def ;
1510
    HASHID macro ;
1511
    int ret = lex_ignore_token ;
1512
    int t = read_token () ;
1513
    update_column () ;
1514
    if ( in_preproc_dir ) preproc_loc = crt_loc ;
1515
    if ( t != lex_identifier ) {
1516
	report ( preproc_loc, ERR_cpp_scope_id ( lex_undef ) ) ;
1517
	return ( ret ) ;
1518
    }
1519
    macro = token_hashid ;
1520
    if ( EQ_KEYWORD ( macro, lex_defined ) ) {
1521
	/* Cannot undefine defined */
1522
	report ( preproc_loc, ERR_cpp_predef_bad ( macro, lex_undef ) ) ;
1523
    }
1524
 
1525
    /* Undefine the macro if necessary */
1526
    def = check_macro ( macro, 0 ) ;
1527
    if ( def == PP_TRUE ) {
1528
	/* Previously defined as macro */
1529
	IDENTIFIER prev = DEREF_id ( hashid_id ( macro ) ) ;
1530
	DECL_SPEC ds = DEREF_dspec ( id_storage ( prev ) ) ;
1531
	if ( ( ds & dspec_builtin ) && crt_file_type == 0 ) {
1532
	    report ( preproc_loc, ERR_cpp_predef_undef ( prev ) ) ;
1533
	}
1534
	if ( do_macro ) dump_undefine ( prev, &preproc_loc, 1 ) ;
1535
	prev = free_macro_defn ( prev ) ;
1536
	COPY_id ( hashid_id ( macro ), prev ) ;
1537
	decr_value ( OPT_VAL_macro_ids ) ;
1538
 
1539
    } else if ( def & PP_TOKEN ) {
1540
	/* Previously defined as token */
1541
	IDENTIFIER prev = token_macro ;
1542
	def &= PP_COND_MASK ;
1543
	if ( def == PP_UNRESOLVED ) {
1544
	    /* Can only happen when preprocessing */
1545
	    ret = lex_hash_Hop ;
1546
	} else {
1547
	    if ( IS_id_function_etc ( prev ) ) {
1548
		do {
1549
		    DECL_SPEC ds = DEREF_dspec ( id_storage ( prev ) ) ;
1550
		    TYPE f = DEREF_type ( id_function_etc_form ( prev ) ) ;
1551
		    if ( !IS_NULL_type ( f ) && IS_type_token ( f ) ) {
1552
			IDENTIFIER ext = DEREF_id ( type_token_tok ( f ) ) ;
1553
			if ( !IS_NULL_id ( ext ) && IS_id_token ( ext ) ) {
1554
			    if ( do_dump ) {
1555
				dump_undefine ( prev, &preproc_loc, 1 ) ;
1556
			    }
1557
			    f = NULL_type ;
1558
			    COPY_type ( id_function_etc_form ( prev ), f ) ;
1559
			}
1560
		    }
1561
		    ds &= ~dspec_token ;
1562
		    COPY_dspec ( id_storage ( prev ), ds ) ;
1563
		    prev = DEREF_id ( id_function_etc_over ( prev ) ) ;
1564
		} while ( !IS_NULL_id ( prev ) ) ;
1565
	    } else {
1566
		if ( do_dump ) dump_undefine ( prev, &preproc_loc, 1 ) ;
1567
		remove_id ( prev ) ;
1568
	    }
1569
	}
1570
 
1571
    } else {
1572
	/* Not previously declared */
1573
	report ( preproc_loc, ERR_cpp_scope_undef ( macro ) ) ;
1574
    }
1575
 
1576
    /* Check the rest of the directive */
1577
    if ( in_preproc_dir && skip_to_end () ) {
1578
	report ( preproc_loc, ERR_cpp_end ( lex_undef ) ) ;
1579
    }
1580
    return ( ret ) ;
1581
}
1582
 
1583
 
1584
/*
1585
    READ A LINE DIRECTIVE
1586
 
1587
    This routine processes a '#line' or '#file' directive (as indicated
1588
    by dir).
1589
*/
1590
 
1591
static void read_location
1592
    PROTO_N ( ( dir ) )
1593
    PROTO_T ( int dir )
1594
{
1595
    /* Read the line */
1596
    PPTOKEN *p = read_line ( lex_ignore_token, lex_ignore_token ) ;
1597
    unsigned long ln = crt_loc.line ;
1598
    string fn = DEREF_string ( posn_file ( crt_loc.posn ) ) ;
1599
    unsigned long ln_old = ln ;
1600
    string fn_old = fn ;
1601
 
1602
    /* Macro expand the line */
1603
    PPTOKEN *q = expand_tok_list ( p ) ;
1604
    q = clean_tok_list ( q ) ;
1605
    if ( q && q->tok == lex_integer_Hlit && dir == lex_line ) {
1606
	/* Process '#line number string-opt' */
1607
	unsigned err = 0 ;
1608
	PPTOKEN *r = q->next ;
1609
	ln = eval_line_digits ( q->pp_data.text, &err ) ;
1610
	if ( ln != ln_old ) crt_line_changed = 1 ;
1611
	if ( err & 2 ) {
1612
	    report ( preproc_loc, ERR_cpp_line_float ( dir ) ) ;
1613
	}
1614
	if ( ( err & 1 ) || ( ln == 0 ) ) {
1615
	    report ( preproc_loc, ERR_cpp_line_range ( dir ) ) ;
1616
	}
1617
	if ( r && r->tok == lex_string_Hlit ) {
1618
	    fn = r->pp_data.str.start ;
1619
	    if ( !ustreq ( fn, fn_old ) ) {
1620
		crt_file_changed = 1 ;
1621
		crt_line_changed = 1 ;
1622
	    }
1623
	    r = r->next ;
1624
	}
1625
	if ( r ) report ( preproc_loc, ERR_cpp_end ( dir ) ) ;
1626
    } else if ( q && q->tok == lex_string_Hlit && dir == lex_file ) {
1627
	/* Process '#file string' */
1628
	PPTOKEN *r = q->next ;
1629
	fn = q->pp_data.str.start ;
1630
	if ( !ustreq ( fn, fn_old ) ) {
1631
	    crt_file_changed = 1 ;
1632
	    crt_line_changed = 1 ;
1633
	}
1634
	if ( r ) report ( preproc_loc, ERR_cpp_end ( dir ) ) ;
1635
    } else {
1636
	report ( preproc_loc, ERR_cpp_line_bad ( dir ) ) ;
1637
    }
1638
    free_tok_list ( p ) ;
1639
    free_tok_list ( q ) ;
1640
    if ( crt_line_changed ) {
1641
	PTR ( POSITION ) posn = crt_loc.posn ;
1642
	string d = DEREF_string ( posn_dir ( posn ) ) ;
1643
	string input = DEREF_string ( posn_input ( posn ) ) ;
1644
	unsigned long off = DEREF_ulong ( posn_offset ( posn ) ) ;
1645
	unsigned long date = DEREF_ulong ( posn_datestamp ( posn ) ) ;
1646
	PTR ( LOCATION ) from = DEREF_ptr ( posn_from ( posn ) ) ;
1647
	off += ( ln - ln_old ) ;
1648
	posn = MAKE_ptr ( SIZE_posn ) ;
1649
	MAKE_posn ( fn, input, fn, d, off, from, date, posn ) ;
1650
	crt_loc.posn = posn ;
1651
    }
1652
    crt_loc.line = ln ;
1653
    crt_loc.column = 0 ;
1654
    return ;
1655
}
1656
 
1657
 
1658
/*
1659
    READ AN ERROR DIRECTIVE
1660
 
1661
    This routine processes a '#error' or '#warning' directive (as indicated
1662
    by the error severity level sev).
1663
*/
1664
 
1665
static void read_error
1666
    PROTO_N ( ( opt ) )
1667
    PROTO_T ( int opt )
1668
{
1669
    ERROR err ;
1670
    PPTOKEN *p = read_line ( lex_ignore_token, lex_ignore_token ) ;
1671
    IGNORE quote_tok_list ( p, 0, char_quote ) ;
1672
    err = ERR_cpp_error_msg ( token_buff.start ) ;
1673
    if ( !IS_NULL_err ( err ) ) {
1674
	err = set_severity ( err, opt, 0 ) ;
1675
	report ( preproc_loc, err ) ;
1676
    }
1677
    free_tok_list ( p ) ;
1678
    return ;
1679
}
1680
 
1681
 
1682
/*
1683
    READ AN IDENT DIRECTIVE
1684
 
1685
    This routine processes a '#ident' directive.
1686
*/
1687
 
1688
void read_ident
1689
    PROTO_N ( ( dir ) )
1690
    PROTO_T ( int dir )
1691
{
1692
    int t = read_token () ;
1693
    update_column () ;
1694
    if ( in_preproc_dir ) preproc_loc = crt_loc ;
1695
    if ( t == lex_string_Hlit ) {
1696
	string s = token_buff.start ;
1697
	unsigned long n = ( unsigned long ) ( token_buff.posn - s ) ;
1698
	compile_comment ( s, n ) ;
1699
	if ( in_preproc_dir && skip_to_end () ) {
1700
	    report ( preproc_loc, ERR_cpp_end ( dir ) ) ;
1701
	}
1702
    } else {
1703
	report ( preproc_loc, ERR_pragma_cpp_ident ( dir ) ) ;
1704
    }
1705
    return ;
1706
}
1707
 
1708
 
1709
/*
1710
    CREATE AN ASSERTION
1711
 
1712
    This routine looks up the assertion named pred, creating it if it does
1713
    not already exist.
1714
*/
1715
 
1716
IDENTIFIER make_assert
1717
    PROTO_N ( ( pred, key ) )
1718
    PROTO_T ( HASHID pred X int key )
1719
{
1720
    NAMESPACE ns = assert_namespace ;
1721
    MEMBER mem = search_member ( ns, pred, 1 ) ;
1722
    IDENTIFIER id = DEREF_id ( member_id ( mem ) ) ;
1723
    if ( IS_NULL_id ( id ) ) {
1724
	/* Define assertion if not already defined */
1725
	MAKE_id_predicate ( pred, dspec_none, ns, preproc_loc, id ) ;
1726
	COPY_ulong ( id_no ( id ), ( unsigned long ) key ) ;
1727
	COPY_id ( member_id ( mem ), id ) ;
1728
    }
1729
    return ( id ) ;
1730
}
1731
 
1732
 
1733
/*
1734
    SKIP A PREDICATE
1735
 
1736
    This routine skips a predicate given by the list of preprocessing
1737
    tokens p.  It is entered after the initial open bracket and returns
1738
    the token after the matching close bracket.
1739
*/
1740
 
1741
static PPTOKEN *skip_predicate
1742
    PROTO_N ( ( p, dir ) )
1743
    PROTO_T ( PPTOKEN **p X int dir )
1744
{
1745
    PPTOKEN *q = *p ;
1746
    PPTOKEN *r = NULL ;
1747
    int bracket = 1 ;
1748
    if ( q ) q->pp_space = 0 ;
1749
    while ( q ) {
1750
	int t = q->tok ;
1751
	if ( t == lex_open_Hround ) {
1752
	    /* Increase bracket count */
1753
	    bracket++ ;
1754
	} else if ( t == lex_close_Hround ) {
1755
	    /* Decrease bracket count */
1756
	    if ( --bracket == 0 ) {
1757
		if ( r ) {
1758
		    r->next = NULL ;
1759
		} else if ( dir == lex_define || dir == lex_undef ) {
1760
		    *p = NULL ;
1761
		} else {
1762
		    report ( preproc_loc, ERR_pragma_assert_empty ( dir ) ) ;
1763
		    *p = NULL ;
1764
		}
1765
		r = q->next ;
1766
		q->next = free_tokens ;
1767
		free_tokens = q ;
1768
		return ( r ) ;
1769
	    }
1770
	} else if ( t == lex_newline ) {
1771
	    /* Terminate if a newline is reached */
1772
	    report ( preproc_loc, ERR_pragma_assert_paren ( dir ) ) ;
1773
	    if ( r ) {
1774
		r->next = NULL ;
1775
	    } else {
1776
		report ( preproc_loc, ERR_pragma_assert_empty ( dir ) ) ;
1777
		*p = NULL ;
1778
	    }
1779
	    return ( q ) ;
1780
	}
1781
	r = q ;
1782
	q = q->next ;
1783
    }
1784
    report ( preproc_loc, ERR_pragma_assert_paren ( dir ) ) ;
1785
    return ( NULL ) ;
1786
}
1787
 
1788
 
1789
/*
1790
    CHECK A PREDICATE VALUE
1791
 
1792
    This routine checks whether the value p, or any value if def is true,
1793
    has been defined in the predicate pred.
1794
*/
1795
 
1796
static int check_assert
1797
    PROTO_N ( ( pred, p, def ) )
1798
    PROTO_T ( HASHID pred X PPTOKEN *p X int def )
1799
{
1800
    IDENTIFIER id = make_assert ( pred, lex_unknown ) ;
1801
    int key = ( int ) DEREF_ulong ( id_no ( id ) ) ;
1802
    LIST ( PPTOKEN_P ) s = DEREF_list ( id_predicate_values ( id ) ) ;
1803
    report ( preproc_loc, ERR_pragma_assert_pred ( pred ) ) ;
1804
    if ( def ) {
1805
	/* Check for any predicate */
1806
	if ( !IS_NULL_list ( s ) ) return ( 1 ) ;
1807
    } else {
1808
	while ( !IS_NULL_list ( s ) ) {
1809
	    PPTOKEN *q = DEREF_pptok ( HEAD_list ( s ) ) ;
1810
	    if ( eq_pptok ( p, q ) == 2 ) return ( 1 ) ;
1811
	    s = TAIL_list ( s ) ;
1812
	}
1813
    }
1814
    if ( key == lex_include ) {
1815
	/* '#include' checks for included files */
1816
	if ( def ) return ( 1 ) ;
1817
	IGNORE quote_tok_list ( p, 0, char_quote ) ;
1818
	return ( start_include ( token_buff.start, char_quote, 4, 0 ) ) ;
1819
    }
1820
    if ( key == lex_keyword ) {
1821
	/* '#keyword' checks for keywords */
1822
	if ( def ) return ( 1 ) ;
1823
	if ( p && p->next == NULL ) {
1824
	    if ( p->tok == lex_identifier ) {
1825
		IDENTIFIER pid = p->pp_data.id.use ;
1826
		if ( IS_id_keyword ( pid ) ) return ( 1 ) ;
1827
		if ( IS_id_iso_keyword ( pid ) ) return ( 1 ) ;
1828
	    }
1829
	}
1830
    }
1831
    if ( key == lex_option ) {
1832
	/* '#option' checks for options */
1833
	int n ;
1834
	ulong sn ;
1835
	string sb ;
1836
	static STRING str = NULL_str ;
1837
	if ( def ) return ( 1 ) ;
1838
	IGNORE quote_tok_list ( p, 0, char_quote ) ;
1839
	sb = token_buff.start ;
1840
	sn = ( ulong ) ( token_buff.posn - sb ) ;
1841
	if ( IS_NULL_str ( str ) ) {
1842
	    MAKE_str_simple ( sn, sb, STRING_NONE, str ) ;
1843
	} else {
1844
	    COPY_string ( str_simple_text ( str ), sb ) ;
1845
	    COPY_ulong ( str_simple_len ( str ), sn ) ;
1846
	}
1847
	n = find_option_no ( str, 0 ) ;
1848
	if ( n != -1 && option ( n ) ) return ( 1 ) ;
1849
    }
1850
    return ( 0 ) ;
1851
}
1852
 
1853
 
1854
/*
1855
    SET A PREDICATE VALUE
1856
 
1857
    This routine sets the assertion value of the preprocessing tokens p
1858
    in the predicate id to be def.
1859
*/
1860
 
1861
static void set_assert
1862
    PROTO_N ( ( id, p, def ) )
1863
    PROTO_T ( IDENTIFIER id X PPTOKEN *p X int def )
1864
{
1865
    LIST ( PPTOKEN_P ) s ;
1866
    PTR ( LIST ( PPTOKEN_P ) ) ps = id_predicate_values ( id ) ;
1867
    LIST ( PPTOKEN_P ) r = DEREF_list ( ps ) ;
1868
    while ( s = DEREF_list ( ps ), !IS_NULL_list ( s ) ) {
1869
	PPTOKEN *q = DEREF_pptok ( HEAD_list ( s ) ) ;
1870
	if ( eq_pptok ( p, q ) == 2 ) {
1871
	    /* Already asserted */
1872
	    if ( !def ) {
1873
		DESTROY_CONS_pptok ( destroy, q, s, s ) ;
1874
		COPY_list ( ps, s ) ;
1875
		free_tok_list ( q ) ;
1876
	    }
1877
	    free_tok_list ( p ) ;
1878
	    return ;
1879
	}
1880
	ps = PTR_TAIL_list ( s ) ;
1881
    }
1882
    if ( def ) {
1883
	/* Create assertion */
1884
	CONS_pptok ( p, r, r ) ;
1885
	COPY_list ( id_predicate_values ( id ), r ) ;
1886
    } else {
1887
	free_tok_list ( p ) ;
1888
    }
1889
    return ;
1890
}
1891
 
1892
 
1893
/*
1894
    READ AN ASSERT DIRECTIVE
1895
 
1896
    This routine processes a '#assert' directive.
1897
*/
1898
 
1899
static void read_assert
1900
    PROTO_N ( ( dir ) )
1901
    PROTO_T ( int dir )
1902
{
1903
    /* Read the predicate name */
1904
    int def = 1 ;
1905
    IDENTIFIER id ;
1906
    PPTOKEN *p, *q ;
1907
    int t = read_token () ;
1908
    update_column () ;
1909
    if ( in_preproc_dir ) preproc_loc = crt_loc ;
1910
    if ( t != lex_identifier ) {
1911
	report ( preproc_loc, ERR_pragma_assert_id ( dir ) ) ;
1912
	return ;
1913
    }
1914
    id = make_assert ( token_hashid, lex_unknown ) ;
1915
 
1916
    /* Read the predicate token sequence */
1917
    t = read_token () ;
1918
    update_column () ;
1919
    if ( in_preproc_dir ) preproc_loc = crt_loc ;
1920
    if ( t != lex_open_Hround ) {
1921
	report ( preproc_loc, ERR_pragma_assert_open ( dir ) ) ;
1922
	return ;
1923
    }
1924
    p = read_line ( lex_ignore_token, lex_ignore_token ) ;
1925
    q = skip_predicate ( &p, dir ) ;
1926
    if ( q ) {
1927
	report ( preproc_loc, ERR_cpp_end ( dir ) ) ;
1928
	free_tok_list ( q ) ;
1929
    }
1930
 
1931
    /* Create the assertion */
1932
    if ( p ) set_assert ( id, p, def ) ;
1933
    return ;
1934
}
1935
 
1936
 
1937
/*
1938
    READ AN UNASSERT DIRECTIVE
1939
 
1940
    This routine processes a '#unassert' directive.
1941
*/
1942
 
1943
static void read_unassert
1944
    PROTO_N ( ( dir ) )
1945
    PROTO_T ( int dir )
1946
{
1947
    /* Read the predicate name */
1948
    IDENTIFIER id ;
1949
    PPTOKEN *p, *q ;
1950
    int t = read_token () ;
1951
    update_column () ;
1952
    if ( in_preproc_dir ) preproc_loc = crt_loc ;
1953
    if ( t != lex_identifier ) {
1954
	report ( preproc_loc, ERR_pragma_assert_id ( dir ) ) ;
1955
	return ;
1956
    }
1957
    id = make_assert ( token_hashid, lex_unknown ) ;
1958
 
1959
    /* Check for simple identifier */
1960
    t = read_token () ;
1961
    update_column () ;
1962
    if ( in_preproc_dir ) preproc_loc = crt_loc ;
1963
    if ( t == lex_newline ) {
1964
	p = NULL ;
1965
    } else {
1966
	/* Read the predicate token sequence */
1967
	if ( t != lex_open_Hround ) {
1968
	    report ( preproc_loc, ERR_pragma_assert_open ( dir ) ) ;
1969
	    return ;
1970
	}
1971
	p = read_line ( lex_ignore_token, lex_ignore_token ) ;
1972
	q = skip_predicate ( &p, dir ) ;
1973
	if ( q ) {
1974
	    report ( preproc_loc, ERR_cpp_end ( dir ) ) ;
1975
	    free_tok_list ( q ) ;
1976
	}
1977
    }
1978
 
1979
    if ( p == NULL ) {
1980
	/* Unassert all values */
1981
	LIST ( PPTOKEN_P ) r ;
1982
	r = DEREF_list ( id_predicate_values ( id ) ) ;
1983
	while ( !IS_NULL_list ( r ) ) {
1984
	    DESTROY_CONS_pptok ( destroy, q, r, r ) ;
1985
	    free_tok_list ( q ) ;
1986
	}
1987
	COPY_list ( id_predicate_values ( id ), r ) ;
1988
	COPY_ulong ( id_no ( id ), lex_unknown ) ;
1989
    } else {
1990
	/* Destroy the assertion */
1991
	set_assert ( id, p, 0 ) ;
1992
    }
1993
    return ;
1994
}
1995
 
1996
 
1997
/*
1998
    LOOK UP AN IDENTIFIER IN A PRAGMA WEAK DIRECTIVE
1999
 
2000
    This routine looks up the identifier named nm used in a '#pragma
2001
    weak' directive.  The result should be an external variable or
2002
    function.  The null identifier is returned to indicate an error.
2003
*/
2004
 
2005
static IDENTIFIER find_weak_id
2006
    PROTO_N ( ( nm ) )
2007
    PROTO_T ( HASHID nm )
2008
{
2009
    if ( !IS_NULL_hashid ( nm ) ) {
2010
	ERROR err ;
2011
	IDENTIFIER id = find_id ( nm ) ;
2012
	switch ( TAG_id ( id ) ) {
2013
	    case id_variable_tag : {
2014
		DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
2015
		if ( !( ds & dspec_auto ) ) {
2016
		    ds |= dspec_used ;
2017
		    COPY_dspec ( id_storage ( id ), ds ) ;
2018
		    return ( id ) ;
2019
		}
2020
		break ;
2021
	    }
2022
	    case id_function_tag : {
2023
		TYPE t = DEREF_type ( id_function_type ( id ) ) ;
2024
		IDENTIFIER over = DEREF_id ( id_function_over ( id ) ) ;
2025
		if ( IS_NULL_id ( over ) && IS_type_func ( t ) ) {
2026
		    DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
2027
		    ds |= dspec_used ;
2028
		    COPY_dspec ( id_storage ( id ), ds ) ;
2029
		    return ( id ) ;
2030
		}
2031
		break ;
2032
	    }
2033
	}
2034
	err = ERR_pragma_preserve_undecl ( lex_weak, id ) ;
2035
	report ( preproc_loc, err ) ;
2036
    }
2037
    return ( NULL_id ) ;
2038
}
2039
 
2040
 
2041
/*
2042
    READ A PRAGMA WEAK DIRECTIVE
2043
 
2044
    This routine processes a '#pragma weak' directive.
2045
*/
2046
 
2047
void read_weak
2048
    PROTO_N ( ( dir ) )
2049
    PROTO_T ( int dir )
2050
{
2051
    IDENTIFIER id = NULL_id ;
2052
    IDENTIFIER aid = NULL_id ;
2053
    int t = read_token () ;
2054
    update_column () ;
2055
    if ( in_preproc_dir ) preproc_loc = crt_loc ;
2056
    if ( t == lex_identifier ) {
2057
	id = find_weak_id ( token_hashid ) ;
2058
	t = read_token () ;
2059
	update_column () ;
2060
	if ( in_preproc_dir ) preproc_loc = crt_loc ;
2061
	if ( t == lex_assign ) {
2062
	    t = read_token () ;
2063
	    update_column () ;
2064
	    if ( in_preproc_dir ) preproc_loc = crt_loc ;
2065
	    if ( t == lex_identifier ) {
2066
		aid = find_weak_id ( token_hashid ) ;
2067
		t = read_token () ;
2068
		update_column () ;
2069
		if ( in_preproc_dir ) preproc_loc = crt_loc ;
2070
	    }
2071
	}
2072
    } else {
2073
	t = lex_unknown ;
2074
    }
2075
    if ( !IS_NULL_id ( aid ) ) {
2076
	static LIST ( IDENTIFIER ) weak_ids = NULL_list ( IDENTIFIER ) ;
2077
	LIST ( IDENTIFIER ) p = weak_ids ;
2078
	while ( !IS_NULL_list ( p ) ) {
2079
	    IDENTIFIER pid = DEREF_id ( HEAD_list ( p ) ) ;
2080
	    if ( EQ_id ( id, pid ) ) {
2081
		report ( preproc_loc, ERR_pragma_weak_redef ( id ) ) ;
2082
		id = NULL_id ;
2083
		break ;
2084
	    }
2085
	    p = TAIL_list ( p ) ;
2086
	}
2087
	if ( !IS_NULL_id ( id ) ) {
2088
	    CONS_id ( id, weak_ids, weak_ids ) ;
2089
	}
2090
    }
2091
    compile_weak ( id, aid ) ;
2092
    if ( t != lex_newline ) {
2093
	report ( preproc_loc, ERR_cpp_end ( dir ) ) ;
2094
    }
2095
    if ( in_preproc_dir ) IGNORE skip_to_end () ;
2096
    return ;
2097
}
2098
 
2099
 
2100
/*
2101
    READ A PREPROCESSING DIRECTIVE
2102
 
2103
    This routine processes a preprocessing directive up to and including
2104
    the terminating newline character.  The act argument indicates
2105
    whether the directive is active or is being skipped in a conditional
2106
    compilation.  prev gives the previous preprocessing directive value.
2107
    The routine returns a lexical token value which is used to
2108
    communicate the effect of the directive on the main processor.  Most
2109
    directives are only visible to the preprocessor, and return one of
2110
    the values lex_ignore_token, lex_end_condition or lex_included (note
2111
    that these are all less than zero).  Other directives (for example,
2112
    target dependent conditionals) do communicate with the main
2113
    processor by returning a valid lexical token value.
2114
*/
2115
 
2116
int read_preproc_dir
2117
    PROTO_N ( ( act, prev ) )
2118
    PROTO_T ( int act X int prev )
2119
{
2120
    int t ;
2121
    ERROR err ;
2122
    HASHID dir ;
2123
    int pp = lex_ignore_token ;
2124
    in_preproc_dir = 1 ;
2125
    preproc_loc = crt_loc ;
2126
 
2127
    /* Read the token following the '#' */
2128
    t = read_token () ;
2129
    update_column () ;
2130
    if ( in_preproc_dir ) preproc_loc = crt_loc ;
2131
    if ( t != lex_identifier ) {
2132
	if ( t == lex_newline || t == lex_eof ) {
2133
	    /* Warn about empty directives */
2134
	    report ( preproc_loc, ERR_cpp_null () ) ;
2135
	    goto end_label ;
2136
	}
2137
	/* Give an error for other directives */
2138
	report ( preproc_loc, ERR_cpp_bad () ) ;
2139
	goto end_label ;
2140
    }
2141
 
2142
    /* Analyse the '#identifier' directive */
2143
    dir = token_hashid ;
2144
    t = find_hashid ( dir ) ;
2145
    switch ( t ) {
2146
 
2147
	case lex_define : {
2148
	    /* Deal with '#define' */
2149
	    if ( act ) {
2150
		pp = read_define () ;
2151
		if ( pp >= 0 ) pp = patch_cond ( pp, t ) ;
2152
	    }
2153
	    goto end_label ;
2154
	}
2155
 
2156
	case lex_else :
2157
	case lex_endif : {
2158
	    /* Deal with '#else' and '#endif' */
2159
	    if ( in_preproc_dir && skip_to_end () ) {
2160
		/* Check end of directive */
2161
		report ( preproc_loc, ERR_cpp_cond_endif_end ( t ) ) ;
2162
	    }
2163
	    pp = read_if ( t, PP_FALSE, lex_ignore_token ) ;
2164
	    if ( act && pp >= 0 ) pp = patch_cond ( pp, t ) ;
2165
	    return ( pp ) ;
2166
	}
2167
 
2168
	case lex_elif : {
2169
	    /* Deal with '#elif' (expression is read in read_if) */
2170
	    report ( preproc_loc, ERR_cpp_old ( t ) ) ;
2171
	    pp = read_if ( t, PP_FALSE, lex_ignore_token ) ;
2172
	    if ( act && pp >= 0 ) pp = patch_cond ( pp, t ) ;
2173
	    return ( pp ) ;
2174
	}
2175
 
2176
	case lex_error : {
2177
	    /* Deal with '#error' */
2178
	    report ( preproc_loc, ERR_cpp_old ( t ) ) ;
2179
	    if ( act ) read_error ( OPT_error ) ;
2180
	    goto end_label ;
2181
	}
2182
 
2183
	case lex_include : {
2184
	    /* Deal with '#include' */
2185
	    pp = read_include ( act, t ) ;
2186
	    return ( pp ) ;
2187
	}
2188
 
2189
	case lex_if : {
2190
	    /* Deal with '#if' */
2191
	    unsigned cond = read_if_exp ( act, t ) ;
2192
	    pp = read_if ( t, cond, lex_ignore_token ) ;
2193
	    if ( act && pp >= 0 ) pp = patch_cond ( pp, t ) ;
2194
	    return ( pp ) ;
2195
	}
2196
 
2197
	case lex_ifdef : {
2198
	    /* Deal with '#ifdef' */
2199
	    unsigned cond = read_if_def ( act, t, prev ) ;
2200
	    pp = read_if ( t, cond, prev ) ;
2201
	    if ( act && pp >= 0 ) pp = patch_cond ( pp, t ) ;
2202
	    return ( pp ) ;
2203
	}
2204
 
2205
	case lex_ifndef : {
2206
	    /* Deal with '#ifndef' */
2207
	    unsigned cond = read_if_def ( act, t, prev ) ;
2208
	    pp = read_if ( t, negate_cond ( cond ), prev ) ;
2209
	    if ( act && pp >= 0 ) pp = patch_cond ( pp, t ) ;
2210
	    return ( pp ) ;
2211
	}
2212
 
2213
	case lex_line : {
2214
	    /* Deal with '#line' */
2215
	    if ( act ) read_location ( t ) ;
2216
	    goto end_label ;
2217
	}
2218
 
2219
	case lex_pragma : {
2220
	    /* Deal with '#pragma' */
2221
	    if ( act ) {
2222
		int ts = have_type_specifier ;
2223
		int td = have_type_declaration ;
2224
		int fd = have_func_declarator ;
2225
		QUALIFIER cq = crt_id_qualifier ;
2226
		in_pragma_dir = 1 ;
2227
		pp = read_pragma () ;
2228
		in_pragma_dir = 0 ;
2229
		pragma_number = 0 ;
2230
		crt_id_qualifier = cq ;
2231
		have_type_specifier = ts ;
2232
		have_type_declaration = td ;
2233
		have_func_declarator = fd ;
2234
	    }
2235
	    goto end_label ;
2236
	}
2237
 
2238
	case lex_undef : {
2239
	    /* Deal with '#undef' */
2240
	    if ( act ) {
2241
		pp = read_undef () ;
2242
		if ( pp >= 0 ) pp = patch_cond ( pp, t ) ;
2243
	    }
2244
	    goto end_label ;
2245
	}
2246
 
2247
	case lex_assert : {
2248
	    /* Deal with '#assert' (extension) */
2249
	    OPTION opt = option ( OPT_ppdir_assert ) ;
2250
	    if ( opt != OPTION_DISALLOW ) {
2251
		if ( opt != OPTION_ALLOW ) {
2252
		    err = ERR_pragma_cpp_known ( t ) ;
2253
		    err = set_severity ( err, OPT_ppdir_assert, 0 ) ;
2254
		    report ( preproc_loc, err ) ;
2255
		}
2256
		if ( act && !option ( OPT_ppdir_assert_ignore ) ) {
2257
		    read_assert ( t ) ;
2258
		}
2259
		goto end_label ;
2260
	    }
2261
	    break ;
2262
	}
2263
 
2264
	case lex_file : {
2265
	    /* Deal with '#file' (extension) */
2266
	    OPTION opt = option ( OPT_ppdir_file ) ;
2267
	    if ( opt != OPTION_DISALLOW ) {
2268
		if ( opt != OPTION_ALLOW ) {
2269
		    err = ERR_pragma_cpp_known ( t ) ;
2270
		    err = set_severity ( err, OPT_ppdir_file, 0 ) ;
2271
		    report ( preproc_loc, err ) ;
2272
		}
2273
		if ( act && !option ( OPT_ppdir_file_ignore ) ) {
2274
		    read_location ( t ) ;
2275
		}
2276
		goto end_label ;
2277
	    }
2278
	    break ;
2279
	}
2280
 
2281
	case lex_ident : {
2282
	    /* Deal with '#ident' (extension) */
2283
	    OPTION opt = option ( OPT_ppdir_ident ) ;
2284
	    if ( opt != OPTION_DISALLOW ) {
2285
		if ( opt != OPTION_ALLOW ) {
2286
		    err = ERR_pragma_cpp_known ( t ) ;
2287
		    err = set_severity ( err, OPT_ppdir_ident, 0 ) ;
2288
		    report ( preproc_loc, err ) ;
2289
		}
2290
		if ( act && !option ( OPT_ppdir_ident_ignore ) ) {
2291
		    read_ident ( t ) ;
2292
		}
2293
		goto end_label ;
2294
	    }
2295
	    break ;
2296
	}
2297
 
2298
	case lex_import :
2299
	case lex_include_Hnext : {
2300
	    /* Deal with '#import' and '#include_next' (extension) */
2301
	    OPTION opt = option ( OPT_ppdir_import ) ;
2302
	    if ( opt != OPTION_DISALLOW ) {
2303
		if ( opt != OPTION_ALLOW ) {
2304
		    err = ERR_pragma_cpp_known ( t ) ;
2305
		    err = set_severity ( err, OPT_ppdir_import, 0 ) ;
2306
		    report ( preproc_loc, err ) ;
2307
		}
2308
		if ( !option ( OPT_ppdir_import_ignore ) ) {
2309
		    pp = read_include ( act, t ) ;
2310
		    return ( pp ) ;
2311
		}
2312
		goto end_label ;
2313
	    }
2314
	    break ;
2315
	}
2316
 
2317
	case lex_unassert : {
2318
	    /* Deal with '#unassert' (extension) */
2319
	    OPTION opt = option ( OPT_ppdir_unassert ) ;
2320
	    if ( opt != OPTION_DISALLOW ) {
2321
		if ( opt != OPTION_ALLOW ) {
2322
		    err = ERR_pragma_cpp_known ( t ) ;
2323
		    err = set_severity ( err, OPT_ppdir_unassert, 0 ) ;
2324
		    report ( preproc_loc, err ) ;
2325
		}
2326
		if ( act && !option ( OPT_ppdir_unassert_ignore ) ) {
2327
		    read_unassert ( t ) ;
2328
		}
2329
		goto end_label ;
2330
	    }
2331
	    break ;
2332
	}
2333
 
2334
	case lex_warning : {
2335
	    /* Deal with '#warning' (extension) */
2336
	    OPTION opt = option ( OPT_ppdir_warning ) ;
2337
	    if ( opt != OPTION_DISALLOW ) {
2338
		if ( opt != OPTION_ALLOW ) {
2339
		    err = ERR_pragma_cpp_known ( t ) ;
2340
		    err = set_severity ( err, OPT_ppdir_warning, 0 ) ;
2341
		    report ( preproc_loc, err ) ;
2342
		}
2343
		if ( act && !option ( OPT_ppdir_warning_ignore ) ) {
2344
		    read_error ( OPT_warning ) ;
2345
		}
2346
		goto end_label ;
2347
	    }
2348
	    break ;
2349
	}
2350
 
2351
	case lex_weak : {
2352
	    /* Deal with '#weak' (extension) */
2353
	    OPTION opt = option ( OPT_ppdir_weak ) ;
2354
	    if ( opt != OPTION_DISALLOW ) {
2355
		if ( opt != OPTION_ALLOW ) {
2356
		    err = ERR_pragma_cpp_known ( t ) ;
2357
		    err = set_severity ( err, OPT_ppdir_weak, 0 ) ;
2358
		    report ( preproc_loc, err ) ;
2359
		}
2360
		if ( act && !option ( OPT_ppdir_weak_ignore ) ) {
2361
		    read_weak ( t ) ;
2362
		}
2363
		goto end_label ;
2364
	    }
2365
	    break ;
2366
	}
2367
    }
2368
 
2369
    /* Unknown directives */
2370
    report ( preproc_loc, ERR_cpp_unknown ( dir ) ) ;
2371
    end_label : {
2372
	if ( in_preproc_dir ) IGNORE skip_to_end () ;
2373
	return ( pp ) ;
2374
    }
2375
}
2376
 
2377
 
2378
/*
2379
    PREPROCESS A FILE
2380
 
2381
    This routine gives the preprocessor entry point for the compiler.  Each
2382
    token is read, preprocessed, and printed.  The white space in the output
2383
    does not necessarily bear any resemblance to that in the input.
2384
*/
2385
 
2386
void preprocess_file
2387
    PROTO_Z ()
2388
{
2389
    int t ;
2390
    FILE *f ;
2391
    string fn ;
2392
    BUFFER *bf ;
2393
    unsigned long ws = 0 ;
2394
    unsigned long ln = 0 ;
2395
    int force_space = preproc_space ;
2396
    static BUFFER preproc_buff = { NULL, NULL, NULL, NULL } ;
2397
 
2398
    /* Initialise input file */
2399
    init_lex () ;
2400
    fn = DEREF_string ( posn_file ( preproc_loc.posn ) ) ;
2401
 
2402
    /* Open output file */
2403
    if ( !open_output ( OUTPUT_PREPROC, text_mode ) ) {
2404
	string nm = output_name [ OUTPUT_PREPROC ] ;
2405
	fail ( ERR_fail_output ( nm ) ) ;
2406
	term_error ( 0 ) ;
2407
	return ;
2408
    }
2409
    f = output_file [ OUTPUT_PREPROC ] ;
2410
    bf = clear_buffer ( &preproc_buff, f ) ;
2411
    fprintf_v ( f, "#line 1 \"%s\"", strlit ( fn ) ) ;
2412
    crt_file_changed = 1 ;
2413
 
2414
    /* Scan through preprocessing tokens */
2415
    while ( t = expand_preproc ( EXPAND_NORMAL ), t != lex_eof ) {
2416
	/* Allow for skipped files */
2417
	if ( crt_file_type ) continue ;
2418
 
2419
	/* Replace keywords by underlying identifier */
2420
	if ( t >= FIRST_KEYWORD && t <= LAST_KEYWORD ) {
2421
	    crt_token->tok = lex_identifier ;
2422
	}
2423
	if ( t == lex_builtin_Hfile ) {
2424
	    fputc_v ( '\n', f ) ;
2425
	    ln++ ;
2426
	    crt_line_changed = 1 ;
2427
	    crt_spaces = 0 ;
2428
	    continue ;
2429
	}
2430
 
2431
	/* Print any required '#line' directives */
2432
	if ( crt_line_changed ) {
2433
	    int ch = crt_file_changed ;
2434
	    unsigned long n = crt_loc.line ;
2435
	    unsigned long sp = crt_spaces ;
2436
	    unsigned long tab = tab_width ;
2437
	    output_buffer ( bf, 0 ) ;
2438
	    if ( ch ) {
2439
		string fm = DEREF_string ( posn_file ( crt_loc.posn ) ) ;
2440
		if ( ch > 1 || !ustreq ( fn, fm ) ) {
2441
		    char *s = strlit ( fm ) ;
2442
		    fprintf_v ( f, "\n\n#line %lu \"%s\"\n", n, s ) ;
2443
		    fn = fm ;
2444
		    ln = n ;
2445
		}
2446
		crt_file_changed = 0 ;
2447
	    }
2448
	    if ( n != ln ) {
2449
		if ( n > ln && n <= ln + 10 ) {
2450
		    for ( ; ln < n ; ln++ ) fputc_v ( '\n', f ) ;
2451
		} else {
2452
		    /* Force '#line' for more than 10 blank lines */
2453
		    fprintf_v ( f, "\n\n#line %lu\n", n ) ;
2454
		}
2455
		ln = n ;
2456
	    }
2457
	    crt_line_changed = 0 ;
2458
 
2459
	    /* Print indentation */
2460
	    ws = sp ;
2461
	    for ( ; sp >= tab ; sp -= tab ) bfputc ( bf, '\t' ) ;
2462
	    for ( ; sp ; sp-- ) bfputc ( bf, ' ' ) ;
2463
 
2464
	    /* Allow for hash symbols */
2465
	    if ( t == lex_hash_H1 ) crt_token->tok = lex_hash_Hhash_H1 ;
2466
	    if ( t == lex_hash_H2 ) crt_token->tok = lex_hash_Hhash_H2 ;
2467
 
2468
	} else {
2469
	    unsigned long sp = crt_spaces ;
2470
	    if ( sp != ws || force_space ) {
2471
		/* Print space */
2472
		ws = sp ;
2473
		bfputc ( bf, ' ' ) ;
2474
	    }
2475
	}
2476
 
2477
	/* Print the token name */
2478
	IGNORE print_pptok ( crt_token, bf, 0 ) ;
2479
    }
2480
    bfputc ( bf, '\n' ) ;
2481
    output_buffer ( bf, 0 ) ;
2482
    close_output ( OUTPUT_PREPROC ) ;
2483
    return ;
2484
}