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

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

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

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

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

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

Subversion Repositories tendra.SVN

Rev

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

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
Line 53... Line 83...
53
#include "symbols.h"
83
#include "symbols.h"
54
#include "tok.h"
84
#include "tok.h"
55
#include "token.h"
85
#include "token.h"
56
#include "ustring.h"
86
#include "ustring.h"
57
#include "variable.h"
87
#include "variable.h"
58
 
88
 
59
 
89
 
60
/*
90
/*
61
    CHECK THAT PRAGMA SYNTAX AND MAIN SYNTAX ARE IN STEP
91
    CHECK THAT PRAGMA SYNTAX AND MAIN SYNTAX ARE IN STEP
62
 
92
 
63
    By including both psyntax.h and syntax.h, the compiler will check
93
    By including both psyntax.h and syntax.h, the compiler will check
64
    that the lex_* macros defined in each are consistent.  Note that
94
    that the lex_* macros defined in each are consistent.  Note that
65
    because the #pragma syntax is the same for both C and C++, this
95
    because the #pragma syntax is the same for both C and C++, this
66
    also checks the consistency of the C and C++ syntaxes.  This is only
96
    also checks the consistency of the C and C++ syntaxes.  This is only
67
    done in development mode.
97
    done in development mode.
68
*/
98
*/
69
 
99
 
70
#ifdef DEBUG
100
#ifdef DEBUG
71
#include "syntax.h"
101
#include "syntax.h"
72
#endif
102
#endif
73
 
103
 
74
 
104
 
75
/*
105
/*
76
    READ A PREPROCESSING TOKEN
106
    READ A PREPROCESSING TOKEN
77
 
107
 
78
    This routine reads the next preprocessing token from the input file.
108
    This routine reads the next preprocessing token from the input file.
79
*/
109
*/
80
 
110
 
81
static PPTOKEN *get_token
111
static PPTOKEN *
82
    PROTO_Z ()
112
get_token(void)
83
{
113
{
84
    PPTOKEN *p = new_pptok () ;
114
	PPTOKEN *p = new_pptok();
85
    int t = read_token () ;
115
	int t = read_token();
86
    update_column () ;
116
	update_column();
87
    p->tok = t ;
117
	p->tok = t;
88
    p->pp_space = WHITE_SPACE ;
118
	p->pp_space = WHITE_SPACE;
89
    p->next = NULL ;
119
	p->next = NULL;
90
    if ( t <= LAST_COMPLEX_TOKEN ) token_parts ( t, p ) ;
120
	if (t <= LAST_COMPLEX_TOKEN) {
-
 
121
		token_parts(t, p);
-
 
122
	}
91
    return ( p ) ;
123
	return(p);
92
}
124
}
93
 
125
 
94
 
126
 
95
/*
127
/*
96
    FIND A KEYWORD LEXICAL TOKEN NUMBER
128
    FIND A KEYWORD LEXICAL TOKEN NUMBER
97
 
129
 
98
    This routine finds the lexical token corresponding to the identifier id.
130
    This routine finds the lexical token corresponding to the identifier id.
99
    If id does not represent an underlying keyword then an error is reported
131
    If id does not represent an underlying keyword then an error is reported
100
    and lex_identifier is returned.
132
    and lex_identifier is returned.
101
*/
133
*/
102
 
-
 
103
int find_keyword
-
 
104
    PROTO_N ( ( id ) )
-
 
105
    PROTO_T ( IDENTIFIER id )
-
 
106
{
-
 
107
    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
-
 
108
    int t = find_hashid ( nm ) ;
-
 
109
    if ( t == lex_identifier ) {
-
 
110
	report ( preproc_loc, ERR_pragma_keyword_bad ( nm ) ) ;
-
 
111
    }
-
 
112
    return ( t ) ;
-
 
113
}
-
 
114
 
-
 
115
 
-
 
116
/*
-
 
117
    DEFINE A KEYWORD
-
 
118
 
134
 
119
    This routine defines id to be a keyword with lexical token number t.
-
 
120
    Certain language extensions are implemented by tokens disguised as
-
 
121
    keywords.
-
 
122
*/
135
int
123
 
-
 
124
void define_keyword
-
 
125
    PROTO_N ( ( id, t ) )
-
 
126
    PROTO_T ( IDENTIFIER id X int t )
136
find_keyword(IDENTIFIER id)
127
{
137
{
-
 
138
	HASHID nm = DEREF_hashid(id_name(id));
128
    switch ( t ) {
139
	int t = find_hashid(nm);
129
	case lex_identifier : {
140
	if (t == lex_identifier) {
130
	    break ;
141
		report(preproc_loc, ERR_pragma_keyword_bad(nm));
131
	}
142
	}
132
	case lex_representation : {
-
 
133
	    TOKEN tok = make_sort ( "ZZZ", 1 ) ;
-
 
134
	    id = make_token_decl ( tok, 0, id, id ) ;
-
 
135
	    token_interface ( id, lex_no_Hdef ) ;
-
 
136
	    COPY_int ( tok_proc_key ( tok ), t ) ;
-
 
137
	    break ;
-
 
138
	}
-
 
139
	case lex_typeof : {
-
 
140
	    TOKEN tok = make_sort ( "SE", 1 ) ;
-
 
141
	    id = make_token_decl ( tok, 0, id, id ) ;
-
 
142
	    token_interface ( id, lex_no_Hdef ) ;
-
 
143
	    COPY_int ( tok_proc_key ( tok ), t ) ;
-
 
144
	    break ;
-
 
145
	}
-
 
146
	default : {
-
 
147
	    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
-
 
148
	    IGNORE make_keyword ( nm, t, NULL_id ) ;
-
 
149
	    break ;
-
 
150
	}
-
 
151
    }
-
 
152
    return ;
143
	return(t);
153
}
144
}
154
 
145
 
-
 
146
 
-
 
147
/*
-
 
148
    DEFINE A KEYWORD
-
 
149
 
-
 
150
    This routine defines id to be a keyword with lexical token number t.
-
 
151
    Certain language extensions are implemented by tokens disguised as
-
 
152
    keywords.
-
 
153
*/
-
 
154
 
-
 
155
void
-
 
156
define_keyword(IDENTIFIER id, int t)
-
 
157
{
-
 
158
	switch (t) {
-
 
159
	case lex_identifier: {
-
 
160
		break;
-
 
161
	}
-
 
162
	case lex_representation: {
-
 
163
		TOKEN tok = make_sort("ZZZ", 1);
-
 
164
		id = make_token_decl(tok, 0, id, id);
-
 
165
		token_interface(id, lex_no_Hdef);
-
 
166
		COPY_int(tok_proc_key(tok), t);
-
 
167
		break;
-
 
168
	}
-
 
169
	case lex_typeof: {
-
 
170
		TOKEN tok = make_sort("SE", 1);
-
 
171
		id = make_token_decl(tok, 0, id, id);
-
 
172
		token_interface(id, lex_no_Hdef);
-
 
173
		COPY_int(tok_proc_key(tok), t);
-
 
174
		break;
-
 
175
	}
-
 
176
	default: {
-
 
177
		HASHID nm = DEREF_hashid(id_name(id));
-
 
178
		IGNORE make_keyword(nm, t, NULL_id);
-
 
179
		break;
-
 
180
	}
-
 
181
	}
-
 
182
	return;
-
 
183
}
-
 
184
 
155
 
185
 
156
/*
186
/*
157
    UNDEFINE A KEYWORD
187
    UNDEFINE A KEYWORD
158
 
188
 
159
    This routine undefines the keyword id.
189
    This routine undefines the keyword id.
160
*/
190
*/
161
 
191
 
162
void undef_keyword
192
void
163
    PROTO_N ( ( id ) )
-
 
164
    PROTO_T ( IDENTIFIER id )
193
undef_keyword(IDENTIFIER id)
165
{
194
{
166
    unsigned tag ;
195
	unsigned tag;
167
    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
196
	HASHID nm = DEREF_hashid(id_name(id));
168
    PTR ( IDENTIFIER ) ptr = hashid_id ( nm ) ;
197
	PTR(IDENTIFIER)ptr = hashid_id(nm);
169
    do {
198
	do {
170
	IDENTIFIER pid = DEREF_id ( ptr ) ;
199
		IDENTIFIER pid = DEREF_id(ptr);
171
	tag = TAG_id ( pid ) ;
200
		tag = TAG_id(pid);
172
	switch ( tag ) {
201
		switch (tag) {
173
	    case id_keyword_tag :
202
		case id_keyword_tag:
174
	    case id_iso_keyword_tag :
203
		case id_iso_keyword_tag:
175
	    case id_reserved_tag : {
204
		case id_reserved_tag:
176
		/* Undefine a keyword */
205
			/* Undefine a keyword */
-
 
206
			if (do_keyword) {
177
		if ( do_keyword ) dump_undefine ( pid, &preproc_loc, 1 ) ;
207
				dump_undefine(pid, &preproc_loc, 1);
-
 
208
			}
178
		pid = DEREF_id ( id_alias ( pid ) ) ;
209
			pid = DEREF_id(id_alias(pid));
179
		COPY_id ( ptr, pid ) ;
210
			COPY_id(ptr, pid);
180
		COPY_id ( hashid_cache ( nm ), NULL_id ) ;
211
			COPY_id(hashid_cache(nm), NULL_id);
181
		return ;
212
			return;
182
	    }
-
 
183
	}
213
		}
184
	ptr = id_alias ( pid ) ;
214
		ptr = id_alias(pid);
185
    } while ( tag != id_dummy_tag ) ;
215
	} while (tag != id_dummy_tag);
186
    return ;
216
	return;
187
}
217
}
188
 
218
 
189
 
219
 
190
/*
220
/*
191
    RESCAN A PRAGMA STATEMENT
221
    RESCAN A PRAGMA STATEMENT
192
 
222
 
193
    The routine read_tendra replaces all identifier tokens within a '#pragma'
223
    The routine read_tendra replaces all identifier tokens within a '#pragma'
194
    command by their corresponding underlying keywords.  This routine restores
224
    command by their corresponding underlying keywords.  This routine restores
195
    these keywords, except that given by s, to identifiers.
225
    these keywords, except that given by s, to identifiers.
196
*/
226
*/
197
 
227
 
198
void rescan_pragma
228
void
199
    PROTO_N ( ( s ) )
-
 
200
    PROTO_T ( int s )
229
rescan_pragma(int s)
201
{
230
{
202
    PPTOKEN *p ;
231
	PPTOKEN *p;
203
    for ( p = crt_token ; p != NULL ; p = p->next ) {
232
	for (p = crt_token; p != NULL; p = p->next) {
204
	int t = p->tok ;
233
		int t = p->tok;
205
	if ( t >= FIRST_KEYWORD && t <= LAST_KEYWORD && t != s ) {
234
		if (t >= FIRST_KEYWORD && t <= LAST_KEYWORD && t != s) {
206
	    p->tok = lex_identifier ;
235
			p->tok = lex_identifier;
-
 
236
		}
207
	}
237
	}
208
    }
-
 
209
    return ;
238
	return;
210
}
239
}
211
 
240
 
212
 
241
 
213
/*
242
/*
214
    SET A TOKEN TO A KEYWORD
243
    SET A TOKEN TO A KEYWORD
215
 
244
 
216
    This routine sets the preprocessing token p to the keyword corresponding
245
    This routine sets the preprocessing token p to the keyword corresponding
217
    to the lexical token number t.
246
    to the lexical token number t.
218
*/
247
*/
219
 
248
 
220
static void set_token
249
static void
221
    PROTO_N ( ( p, t ) )
-
 
222
    PROTO_T ( PPTOKEN *p X int t )
250
set_token(PPTOKEN *p, int t)
223
{
251
{
224
    HASHID nm = KEYWORD ( t ) ;
252
	HASHID nm = KEYWORD(t);
225
    p->tok = t ;
253
	p->tok = t;
226
    p->pp_data.id.hash = nm ;
254
	p->pp_data.id.hash = nm;
227
    p->pp_data.id.use = DEREF_id ( hashid_id ( nm ) ) ;
255
	p->pp_data.id.use = DEREF_id(hashid_id(nm));
228
    return ;
256
	return;
229
}
257
}
230
 
258
 
231
 
259
 
232
/*
260
/*
233
    PATCH A PRAGMA STATEMENT
261
    PATCH A PRAGMA STATEMENT
234
 
262
 
235
    This routine is used by the preprocessor to preserve a '#pragma'
263
    This routine is used by the preprocessor to preserve a '#pragma'
236
    statement.  The arguments are as in parse_pragma.
264
    statement.  The arguments are as in parse_pragma.
237
*/
265
*/
238
 
266
 
239
static void patch_pragma
267
static void
240
    PROTO_N ( ( p, tendra ) )
-
 
241
    PROTO_T ( PPTOKEN *p X int tendra )
268
patch_pragma(PPTOKEN *p, int tendra)
242
{
269
{
243
    p = clean_tok_list ( p ) ;
270
	p = clean_tok_list(p);
244
    switch ( p->tok ) {
271
	switch (p->tok) {
245
	case lex_interface : {
272
	case lex_interface: {
246
	    int t = crt_interface ;
273
		int t = crt_interface;
247
	    if ( t == lex_ignore && tendra ) t = lex_reject ;
274
		if (t == lex_ignore && tendra) {
-
 
275
			t = lex_reject;
-
 
276
		}
248
	    set_token ( p, t ) ;
277
		set_token(p, t);
249
	    break ;
278
		break;
250
	}
279
	}
251
	case lex_member : {
280
	case lex_member:
252
	    if ( !tendra ) {
281
		if (!tendra) {
253
		if ( p->next->tok == lex_definition ) {
282
			if (p->next->tok == lex_definition) {
254
		    set_token ( p, lex_define_Hcap ) ;
283
				set_token(p, lex_define_Hcap);
255
		    set_token ( p->next, lex_member_Hcap ) ;
284
				set_token(p->next, lex_member_Hcap);
256
		}
285
			}
257
	    }
286
		}
258
	    break ;
287
		break;
259
	}
-
 
260
	case lex_promoted : {
288
	case lex_promoted:
261
	    if ( !tendra ) set_token ( p, lex_promote ) ;
289
		if (!tendra) {
262
	    break ;
290
			set_token(p, lex_promote);
263
	}
291
		}
-
 
292
		break;
264
	case lex_reject : {
293
	case lex_reject:
-
 
294
		if (!tendra) {
265
	    if ( !tendra ) set_token ( p, lex_ignore ) ;
295
			set_token(p, lex_ignore);
-
 
296
		}
266
	    break ;
297
		break;
267
	}
298
	}
268
    }
-
 
269
    patch_preproc_dir ( p ) ;
299
	patch_preproc_dir(p);
270
    if ( tendra ) {
300
	if (tendra) {
271
	p = patch_tokens ( tendra ) ;
301
		p = patch_tokens(tendra);
272
	set_token ( p, lex_tendra ) ;
302
		set_token(p, lex_tendra);
273
	if ( tendra == 2 ) p->next->tok = lex_plus_Hplus ;
303
		if (tendra == 2)p->next->tok = lex_plus_Hplus;
274
    }
304
	}
275
    return ;
305
	return;
276
}
306
}
277
 
307
 
278
 
308
 
279
/*
309
/*
280
    PARSE A PRAGMA STATEMENT
310
    PARSE A PRAGMA STATEMENT
281
 
311
 
282
    This routine parses the '#pragma' statement given by the preprocessing
312
    This routine parses the '#pragma' statement given by the preprocessing
283
    tokens p.  tendra is 1 for '#pragma TenDRA' statements, 2 for '#pragma
313
    tokens p.  tendra is 1 for '#pragma TenDRA' statements, 2 for '#pragma
284
    TenDRA++' statements, and 0 otherwise.
314
    TenDRA++' statements, and 0 otherwise.
285
*/
315
*/
286
 
316
 
287
static int parse_pragma
317
static int
288
    PROTO_N ( ( p, tendra ) )
-
 
289
    PROTO_T ( PPTOKEN *p X int tendra )
318
parse_pragma(PPTOKEN *p, int tendra)
290
{
319
{
291
    int nt ;
320
	int nt;
292
    PPTOKEN *pt ;
321
	PPTOKEN *pt;
293
    PARSE_STATE s ;
322
	PARSE_STATE s;
294
    int pp = preproc_only ;
323
	int pp = preproc_only;
295
    int tok = lex_ignore_token ;
324
	int tok = lex_ignore_token;
296
 
325
 
297
    /* Parsing action */
326
	/* Parsing action */
298
    new_linkage = crt_linkage ;
327
	new_linkage = crt_linkage;
299
    save_state ( &s, 0 ) ;
328
	save_state(&s, 0);
300
    init_parser ( p ) ;
329
	init_parser(p);
301
    crt_loc = preproc_loc ;
330
	crt_loc = preproc_loc;
302
    crt_line_changed = 1 ;
331
	crt_line_changed = 1;
303
    ADVANCE_LEXER ;
332
	ADVANCE_LEXER;
304
    if ( pp ) {
333
	if (pp) {
305
	parse_preproc ( &tok ) ;
334
		parse_preproc(&tok);
306
	if ( tok != lex_ignore_token ) {
335
		if (tok != lex_ignore_token) {
307
	    tok = lex_ignore_token ;
336
			tok = lex_ignore_token;
308
	    have_syntax_error = 1 ;
337
			have_syntax_error = 1;
309
	}
338
		}
310
    } else {
339
	} else {
311
	parse_tendra ( &tok ) ;
340
		parse_tendra(&tok);
312
    }
341
	}
313
    nt = crt_lex_token ;
342
	nt = crt_lex_token;
314
    pt = crt_token ;
343
	pt = crt_token;
315
    p = restore_parser () ;
344
	p = restore_parser();
316
 
345
 
317
    /* Check for end of input */
346
	/* Check for end of input */
318
    switch ( tok ) {
347
	switch (tok) {
319
	case lex_set :
348
	case lex_set:
320
	case lex_unused : {
349
	case lex_unused: {
321
	    /* Patch inset pragma statements */
350
		/* Patch inset pragma statements */
322
	    PPTOKEN *q = clean_tok_list ( p ) ;
351
		PPTOKEN *q = clean_tok_list(p);
323
	    PPTOKEN *r = new_pptok () ;
352
		PPTOKEN *r = new_pptok();
324
	    p = q ;
353
		p = q;
325
	    p->tok = tok ;
354
		p->tok = tok;
326
	    while ( q->tok != lex_newline ) q = q->next ;
355
		while (q->tok != lex_newline) {
-
 
356
			q = q->next;
-
 
357
		}
327
	    q->tok = lex_inset_Hend ;
358
		q->tok = lex_inset_Hend;
328
	    r->tok = lex_newline ;
359
		r->tok = lex_newline;
329
	    r->next = q->next ;
360
		r->next = q->next;
330
	    q->next = r ;
361
		q->next = r;
331
	    patch_preproc_dir ( p ) ;
362
		patch_preproc_dir(p);
332
	    tok = lex_inset_Hstart ;
363
		tok = lex_inset_Hstart;
333
	    p = NULL ;
364
		p = NULL;
334
	    break ;
365
		break;
335
	}
366
	}
336
	default : {
367
	default:
337
	    /* Should have reached the end of the line */
368
		/* Should have reached the end of the line */
338
	    if ( nt != lex_newline && !have_syntax_error ) {
369
		if (nt != lex_newline && !have_syntax_error) {
339
		ERROR err = ERR_lex_parse ( pt ) ;
370
			ERROR err = ERR_lex_parse(pt);
340
		err = concat_error ( err, ERR_cpp_end ( lex_pragma ) ) ;
371
			err = concat_error(err, ERR_cpp_end(lex_pragma));
341
		report ( preproc_loc, err ) ;
372
			report(preproc_loc, err);
342
	    }
373
		}
343
	    break ;
374
		break;
344
	}
375
	}
345
    }
-
 
346
 
376
 
347
    /* Preprocessing action */
377
	/* Preprocessing action */
348
    if ( pp ) {
378
	if (pp) {
349
	patch_pragma ( p, tendra ) ;
379
		patch_pragma(p, tendra);
350
	tok = lex_hash_Hpragma ;
380
		tok = lex_hash_Hpragma;
351
    } else {
381
	} else {
352
	free_tok_list ( p ) ;
382
		free_tok_list(p);
353
    }
383
	}
354
    restore_state ( &s ) ;
384
	restore_state(&s);
355
    crt_linkage = new_linkage ;
385
	crt_linkage = new_linkage;
356
    return ( tok ) ;
386
	return(tok);
357
}
387
}
358
 
388
 
359
 
389
 
360
/*
390
/*
361
    SKIP TO NEXT COLON
391
    SKIP TO NEXT COLON
362
 
392
 
363
    This routine scans along the list of preprocessing tokens p until it
393
    This routine scans along the list of preprocessing tokens p until it
364
    finds the first colon.  It then returns the following token.  The null
394
    finds the first colon.  It then returns the following token.  The null
365
    token is returned if there is no colon in p.
395
    token is returned if there is no colon in p.
366
*/
396
*/
367
 
397
 
368
static PPTOKEN *skip_to_colon
398
static PPTOKEN *
369
    PROTO_N ( ( p ) )
-
 
370
    PROTO_T ( PPTOKEN *p )
399
skip_to_colon(PPTOKEN *p)
371
{
400
{
372
    while ( p ) {
401
	while (p) {
373
	PPTOKEN *q = p->next ;
402
		PPTOKEN *q = p->next;
374
	if ( p->tok == lex_colon ) return ( q ) ;
403
		if (p->tok == lex_colon) {
-
 
404
			return(q);
-
 
405
		}
375
	p = q ;
406
		p = q;
376
    }
407
	}
377
    return ( NULL ) ;
408
	return(NULL);
378
}
409
}
379
 
410
 
380
 
411
 
381
/*
412
/*
382
    MARK A TOKEN PARAMETER
413
    MARK A TOKEN PARAMETER
Line 385... Line 416...
385
    tokens p.  This consists of an optional 'TAG' followed by an identifier,
416
    tokens p.  This consists of an optional 'TAG' followed by an identifier,
386
    which is optional if n is false.  Macro expansion of this identifier
417
    which is optional if n is false.  Macro expansion of this identifier
387
    is inhibited.  Macro is true if the identifier is declared in the
418
    is inhibited.  Macro is true if the identifier is declared in the
388
    token namespace.
419
    token namespace.
389
*/
420
*/
390
 
421
 
391
static PPTOKEN *mark_tdf_param
422
static PPTOKEN *
392
    PROTO_N ( ( p, n, macro ) )
-
 
393
    PROTO_T ( PPTOKEN *p X int n X int macro )
423
mark_tdf_param(PPTOKEN *p, int n, int macro)
394
{
-
 
395
    if ( p && p->tok == lex_identifier ) {
-
 
396
	int t = find_hashid ( p->pp_data.id.hash ) ;
-
 
397
	if ( t == lex_tag_Hcap ) {
-
 
398
	    if ( p->next && p->next->tok == lex_identifier ) {
-
 
399
		/* Have 'TAG id' */
-
 
400
		p->tok = t ;
-
 
401
		p = p->next ;
-
 
402
		p->pp_data.id.use = NULL_id ;
-
 
403
	    } else {
-
 
404
		/* Have 'TAG' */
-
 
405
		if ( n == 0 ) {
-
 
406
		    /* Interpret as 'TAG' */
-
 
407
		    p->tok = t ;
-
 
408
		} else {
-
 
409
		    /* Interpret as 'id' where id = TAG */
-
 
410
		    p->pp_data.id.use = NULL_id ;
-
 
411
		}
-
 
412
	    }
-
 
413
	} else {
-
 
414
	    /* Have 'id' */
-
 
415
	    if ( macro && preproc_only ) {
-
 
416
		/* Mark macro names when preprocessing */
-
 
417
		HASHID nm = p->pp_data.id.hash ;
-
 
418
		unsigned c = check_macro ( nm, 0 ) ;
-
 
419
		IDENTIFIER id = underlying_id ( p->pp_data.id.use ) ;
-
 
420
		DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
-
 
421
		ds |= dspec_token ;
-
 
422
		COPY_dspec ( id_storage ( id ), ds ) ;
-
 
423
		if ( c == PP_TRUE ) {
-
 
424
		    /* Token previously defined as macro */
-
 
425
		    PPTOKEN *q ;
-
 
426
		    token_macro = DEREF_id ( hashid_id ( nm ) ) ;
-
 
427
		    IGNORE patch_cond ( lex_hash_Hop, lex_define ) ;
-
 
428
		    q = patch_tokens ( 2 ) ;
-
 
429
		    q->tok = lex_builtin_Hfile ;
-
 
430
		    q->next->tok = lex_hash_Hop ;
-
 
431
		}
-
 
432
	    }
-
 
433
	    p->pp_data.id.use = NULL_id ;
-
 
434
	}
-
 
435
	return ( p->next ) ;
-
 
436
    }
-
 
437
    if ( n ) return ( NULL ) ;
-
 
438
    return ( p ) ;
-
 
439
}
-
 
440
 
-
 
441
 
-
 
442
/*
-
 
443
    MARK A TOKEN PROGRAM PARAMETER
-
 
444
 
-
 
445
    This routine marks the TDF token program parameter given by the
-
 
446
    preprocessing tokens p.
-
 
447
*/
-
 
448
 
-
 
449
static PPTOKEN *mark_prog_param
-
 
450
    PROTO_N ( ( p ) )
-
 
451
    PROTO_T ( PPTOKEN *p )
-
 
452
{
424
{
453
    if ( p && p->tok == lex_identifier ) {
425
	if (p && p->tok == lex_identifier) {
454
	int t = find_hashid ( p->pp_data.id.hash ) ;
426
		int t = find_hashid(p->pp_data.id.hash);
455
	switch ( t ) {
-
 
456
	    case lex_exp_Hcap :
-
 
457
	    case lex_nat_Hcap :
427
		if (t == lex_tag_Hcap) {
458
	    case lex_int_Hcap :
428
			if (p->next && p->next->tok == lex_identifier) {
459
	    case lex_stmt_Hcap :
-
 
460
	    case lex_proc_Hcap : {
-
 
461
		/* Have the form 'EXP id' etc */
429
				/* Have 'TAG id' */
462
		p->tok = t ;
430
				p->tok = t;
463
		p = p->next ;
431
				p = p->next;
464
		if ( p ) p = p->next ;
432
				p->pp_data.id.use = NULL_id;
465
		return ( p ) ;
-
 
466
	    }
433
			} else {
467
	    case lex_type_Hcap : {
-
 
468
		/* Have the form 'TYPE t' */
434
				/* Have 'TAG' */
469
		int depth = 0 ;
-
 
470
		p->tok = t ;
-
 
471
		while ( p ) {
435
				if (n == 0) {
472
		    /* Step over type */
436
					/* Interpret as 'TAG' */
473
		    switch ( p->tok ) {
437
					p->tok = t;
474
			case lex_open_Hround :
438
				} else {
475
			case lex_open_Hsquare_H1 :
439
					/* Interpret as 'id' where id = TAG */
476
			case lex_open_Hsquare_H2 : {
440
					p->pp_data.id.use = NULL_id;
477
			    depth++ ;
-
 
478
			    break ;
-
 
479
			}
441
				}
480
			case lex_close_Hround :
-
 
481
			case lex_close_Hsquare_H1 :
-
 
482
			case lex_close_Hsquare_H2 : {
-
 
483
			    if ( depth > 0 ) depth-- ;
-
 
484
			    break ;
-
 
485
			}
442
			}
-
 
443
		} else {
486
			case lex_comma : {
444
			/* Have 'id' */
487
			    if ( depth == 0 ) return ( p ) ;
445
			if (macro && preproc_only) {
-
 
446
				/* Mark macro names when preprocessing */
-
 
447
				HASHID nm = p->pp_data.id.hash;
-
 
448
				unsigned c = check_macro(nm, 0);
-
 
449
				IDENTIFIER id =
-
 
450
				    underlying_id(p->pp_data.id.use);
-
 
451
				DECL_SPEC ds = DEREF_dspec(id_storage(id));
-
 
452
				ds |= dspec_token;
-
 
453
				COPY_dspec(id_storage(id), ds);
-
 
454
				if (c == PP_TRUE) {
-
 
455
					/* Token previously defined as macro */
488
			    break ;
456
					PPTOKEN *q;
-
 
457
					token_macro = DEREF_id(hashid_id(nm));
-
 
458
					IGNORE patch_cond(lex_hash_Hop,
-
 
459
							  lex_define);
-
 
460
					q = patch_tokens(2);
-
 
461
					q->tok = lex_builtin_Hfile;
-
 
462
					q->next->tok = lex_hash_Hop;
-
 
463
				}
489
			}
464
			}
-
 
465
			p->pp_data.id.use = NULL_id;
-
 
466
		}
-
 
467
		return(p->next);
-
 
468
	}
-
 
469
	if (n) {
-
 
470
		return(NULL);
-
 
471
	}
-
 
472
	return(p);
-
 
473
}
-
 
474
 
-
 
475
 
-
 
476
/*
-
 
477
    MARK A TOKEN PROGRAM PARAMETER
-
 
478
 
-
 
479
    This routine marks the TDF token program parameter given by the
-
 
480
    preprocessing tokens p.
-
 
481
*/
-
 
482
 
-
 
483
static PPTOKEN *
-
 
484
mark_prog_param(PPTOKEN *p)
-
 
485
{
-
 
486
	if (p && p->tok == lex_identifier) {
-
 
487
		int t = find_hashid(p->pp_data.id.hash);
-
 
488
		switch (t) {
-
 
489
		case lex_exp_Hcap:
-
 
490
		case lex_nat_Hcap:
-
 
491
		case lex_int_Hcap:
-
 
492
		case lex_stmt_Hcap:
-
 
493
		case lex_proc_Hcap:
-
 
494
			/* Have the form 'EXP id' etc */
-
 
495
			p->tok = t;
-
 
496
			p = p->next;
-
 
497
			if (p) {
-
 
498
				p = p->next;
-
 
499
			}
-
 
500
			return(p);
-
 
501
		case lex_type_Hcap: {
-
 
502
			/* Have the form 'TYPE t' */
-
 
503
			int depth = 0;
-
 
504
			p->tok = t;
-
 
505
			while (p) {
-
 
506
				/* Step over type */
-
 
507
				switch (p->tok) {
-
 
508
				case lex_open_Hround:
-
 
509
				case lex_open_Hsquare_H1:
-
 
510
				case lex_open_Hsquare_H2:
-
 
511
					depth++;
-
 
512
					break;
-
 
513
				case lex_close_Hround:
490
			case lex_close_Hbrace_H1 :
514
				case lex_close_Hsquare_H1:
491
			case lex_close_Hbrace_H2 : {
515
				case lex_close_Hsquare_H2:
-
 
516
					if (depth > 0) {
-
 
517
						depth--;
-
 
518
					}
-
 
519
					break;
-
 
520
				case lex_comma:
-
 
521
					if (depth == 0) {
492
			    return ( p ) ;
522
						return(p);
493
			}
523
					}
-
 
524
					break;
-
 
525
				case lex_close_Hbrace_H1:
-
 
526
				case lex_close_Hbrace_H2:
-
 
527
					return(p);
494
		    }
528
				}
495
		    p = p->next ;
529
				p = p->next;
496
		}
530
			}
497
		break ;
531
			break;
498
	    }
532
		}
499
	    case lex_member_Hcap : {
533
		case lex_member_Hcap:
500
		/* Have the form 'MEMBER t : id' */
534
			/* Have the form 'MEMBER t : id' */
501
		p->tok = t ;
535
			p->tok = t;
502
		p = skip_to_colon ( p->next ) ;
536
			p = skip_to_colon(p->next);
-
 
537
			if (p) {
503
		if ( p ) p = p->next ;
538
				p = p->next;
-
 
539
			}
504
		return ( p ) ;
540
			return(p);
505
	    }
541
		}
506
	}
542
	}
507
    }
-
 
508
    return ( NULL ) ;
543
	return(NULL);
509
}
544
}
510
 
545
 
511
 
546
 
512
/*
547
/*
513
    MARK A PRAGMA TOKEN STATEMENT
548
    MARK A PRAGMA TOKEN STATEMENT
514
 
549
 
515
    The macro expansion of '#pragma token' statements is rather complex.
550
    The macro expansion of '#pragma token' statements is rather complex.
516
    The token syntax skeleton is not subject to macro expansion, while
551
    The token syntax skeleton is not subject to macro expansion, while
Line 518... Line 553...
518
    the skeleton keywords in the list of preprocessing tokens p, returning
553
    the skeleton keywords in the list of preprocessing tokens p, returning
519
    the token immediately following the token specification.  It also sets
554
    the token immediately following the token specification.  It also sets
520
    macro to true if the declared token lies in the macro namespace.
555
    macro to true if the declared token lies in the macro namespace.
521
*/
556
*/
522
 
557
 
523
static PPTOKEN *mark_tdf_token
558
static PPTOKEN *
524
    PROTO_N ( ( p, macro ) )
-
 
525
    PROTO_T ( PPTOKEN *p X int *macro )
559
mark_tdf_token(PPTOKEN *p, int *macro)
526
{
560
{
622
			}
677
			}
623
			p = mark_tdf_token ( p, macro ) ;
678
			p = mark_tdf_token(p, macro);
624
			p = mark_tdf_param ( p, 0, 0 ) ;
-
 
625
			if ( p == NULL ) break ;
-
 
626
			if ( p->tok == lex_comma ) p = p->next ;
-
 
627
		    }
-
 
628
		}
-
 
629
		p = mark_tdf_token ( p, macro ) ;
-
 
630
		return ( p ) ;
679
			return(p);
631
	    }
-
 
632
 
680
 
633
	    case lex_variety_Hcap : {
681
		case lex_variety_Hcap:
634
		/* Integral type token specifiers */
682
			/* Integral type token specifiers */
635
		p->tok = t ;
683
			p->tok = t;
636
		p = p->next ;
684
			p = p->next;
637
		if ( p->tok == lex_identifier ) {
685
			if (p->tok == lex_identifier) {
638
		    /* Check for signed or unsigned qualifier */
686
				/* Check for signed or unsigned qualifier */
639
		    t = find_hashid ( p->pp_data.id.hash ) ;
687
				t = find_hashid(p->pp_data.id.hash);
640
		    if ( t == lex_signed || t == lex_unsigned ) {
688
				if (t == lex_signed || t == lex_unsigned) {
641
			p->tok = t ;
689
					p->tok = t;
642
			p = p->next ;
690
					p = p->next;
643
		    }
691
				}
-
 
692
			}
-
 
693
			return(p);
-
 
694
 
-
 
695
		case lex_nat_Hcap:
-
 
696
		case lex_int_Hcap:
-
 
697
		case lex_stmt_Hcap:
-
 
698
			/* Simple token specifiers */
-
 
699
			*macro = 1;
-
 
700
			p->tok = t;
-
 
701
			return(p->next);
-
 
702
 
-
 
703
		case lex_arith_Hcap:
-
 
704
		case lex_class_Hcap:
-
 
705
		case lex_float_Hcap:
-
 
706
		case lex_scalar_Hcap:
-
 
707
		case lex_struct_Hcap:
-
 
708
		case lex_type_Hcap:
-
 
709
		case lex_union_Hcap:
-
 
710
			/* Type token specifiers */
-
 
711
			p->tok = t;
-
 
712
			return(p->next);
644
		}
713
		}
645
		return ( p ) ;
-
 
646
	    }
-
 
647
 
-
 
648
	    case lex_nat_Hcap :
-
 
649
	    case lex_int_Hcap :
-
 
650
	    case lex_stmt_Hcap : {
-
 
651
		/* Simple token specifiers */
-
 
652
		*macro = 1 ;
-
 
653
		p->tok = t ;
-
 
654
		return ( p->next ) ;
-
 
655
	    }
-
 
656
 
-
 
657
	    case lex_arith_Hcap :
-
 
658
	    case lex_class_Hcap :
-
 
659
	    case lex_float_Hcap :
-
 
660
	    case lex_scalar_Hcap :
-
 
661
	    case lex_struct_Hcap :
-
 
662
	    case lex_type_Hcap :
-
 
663
	    case lex_union_Hcap : {
-
 
664
		/* Type token specifiers */
-
 
665
		p->tok = t ;
-
 
666
		return ( p->next ) ;
-
 
667
	    }
-
 
668
	}
714
	}
669
    }
-
 
670
    return ( p->next ) ;
715
	return(p->next);
671
}
716
}
672
 
717
 
673
 
718
 
674
/*
719
/*
675
    READ AN EXTERNAL TOKEN NAME
720
    READ AN EXTERNAL TOKEN NAME
676
 
721
 
677
    This routine processes an external token name.  This consists of a
722
    This routine processes an external token name.  This consists of a
678
    hash symbol, pointed to by p, followed a list of preprocessing
723
    hash symbol, pointed to by p, followed a list of preprocessing
679
    tokens.  Note that the result is an extended identifier, unless it
724
    tokens.  Note that the result is an extended identifier, unless it
680
    is a simple identifier.
725
    is a simple identifier.
681
*/
726
*/
682
 
727
 
683
static PPTOKEN *quote_token_name
728
static PPTOKEN *
684
    PROTO_N ( ( p ) )
-
 
685
    PROTO_T ( PPTOKEN *p )
729
quote_token_name(PPTOKEN *p)
686
{
730
{
687
    PPTOKEN *q = p->next ;
731
	PPTOKEN *q = p->next;
688
    if ( q != NULL ) {
732
	if (q != NULL) {
689
	/* All following tokens are quoted */
733
		/* All following tokens are quoted */
690
	string s ;
734
		string s;
691
	unsigned long sp = q->pp_space ;
735
		unsigned long sp = q->pp_space;
692
	IGNORE quote_tok_list ( q, 0, char_quote ) ;
736
		IGNORE quote_tok_list(q, 0, char_quote);
693
	free_tok_list ( q ) ;
737
		free_tok_list(q);
694
	q = new_pptok () ;
738
		q = new_pptok();
695
	q->pp_space = sp ;
739
		q->pp_space = sp;
696
	q->next = NULL ;
740
		q->next = NULL;
697
	s = token_buff.start ;
741
		s = token_buff.start;
698
	if ( ustrseq ( s, "-" ) ) {
742
		if (ustrseq(s, "-")) {
699
	    /* Special form '-' */
743
			/* Special form '-' */
700
	    q->tok = lex_minus ;
744
			q->tok = lex_minus;
701
	} else {
745
		} else {
702
	    /* Create an identifier */
746
			/* Create an identifier */
703
	    unsigned long h = hash ( s ) ;
747
			unsigned long h = hash(s);
704
	    token_hashid = lookup_name ( s, h, 1, lex_unknown ) ;
748
			token_hashid = lookup_name(s, h, 1, lex_unknown);
705
	    q->tok = lex_identifier ;
749
			q->tok = lex_identifier;
706
	    token_parts ( lex_identifier, q ) ;
750
			token_parts(lex_identifier, q);
707
	}
751
		}
708
	p->next = q ;
752
		p->next = q;
709
	p = q ;
753
		p = q;
710
    }
754
	}
711
    return ( p ) ;
755
	return(p);
712
}
756
}
713
 
757
 
714
 
758
 
715
/*
759
/*
716
    READ A PRAGMA TOKEN STATEMENT
760
    READ A PRAGMA TOKEN STATEMENT
717
 
761
 
718
    This routine processes a '#pragma token' statement.  p gives the first
762
    This routine processes a '#pragma token' statement.  p gives the first
719
    preprocessing token (i.e. 'token').  tendra is as in parse_pragma.
763
    preprocessing token (i.e. 'token').  tendra is as in parse_pragma.
720
*/
764
*/
721
 
765
 
722
static int read_tdf_token
766
static int
723
    PROTO_N ( ( p, tendra ) )
-
 
724
    PROTO_T ( PPTOKEN *p X int tendra )
767
read_tdf_token(PPTOKEN *p, int tendra)
725
{
768
{
726
    /* Read and macro expand the rest of the line */
769
	/* Read and macro expand the rest of the line */
727
    int t ;
770
	int t;
728
    PPTOKEN *q = p ;
771
	PPTOKEN *q = p;
729
    while ( q->next ) q = q->next ;
772
	while (q->next)q = q->next;
730
    if ( q->tok != lex_newline ) {
773
	if (q->tok != lex_newline) {
731
	int macro = 0 ;
774
		int macro = 0;
732
	PPTOKEN *r = read_line ( lex_ignore_token, lex_ignore_token ) ;
775
		PPTOKEN *r = read_line(lex_ignore_token, lex_ignore_token);
-
 
776
		if (r) {
733
	if ( r ) r->pp_space = WHITE_SPACE ;
777
			r->pp_space = WHITE_SPACE;
-
 
778
		}
734
	q->next = r ;
779
		q->next = r;
735
	r = mark_tdf_token ( r, &macro ) ;
780
		r = mark_tdf_token(r, &macro);
736
	r = mark_tdf_param ( r, 1, macro ) ;
781
		r = mark_tdf_param(r, 1, macro);
737
	while ( r ) {
782
		while (r) {
738
	    /* Find token name */
783
			/* Find token name */
739
	    t = r->tok ;
784
			t = r->tok;
740
	    if ( t == lex_hash_H1 || t == lex_hash_H2 ) {
785
			if (t == lex_hash_H1 || t == lex_hash_H2) {
741
		q = quote_token_name ( r ) ;
786
				q = quote_token_name(r);
742
		break ;
787
				break;
743
	    }
788
			}
744
	    q = r ;
789
			q = r;
745
	    r = r->next ;
790
			r = r->next;
746
	}
791
		}
747
 
792
 
748
	/* Add newline token */
793
		/* Add newline token */
749
	while ( q->next ) q = q->next ;
794
		while (q->next) {
-
 
795
			q = q->next;
-
 
796
		}
750
	q->next = new_pptok () ;
797
		q->next = new_pptok();
751
	q->next->tok = lex_newline ;
798
		q->next->tok = lex_newline;
752
	q->next->next = NULL ;
799
		q->next->next = NULL;
753
    }
800
	}
754
    q = expand_tok_list ( p ) ;
801
	q = expand_tok_list(p);
755
    free_tok_list ( p ) ;
802
	free_tok_list(p);
756
 
803
 
757
    /* Parse the line */
804
	/* Parse the line */
758
    in_token_decl = 1 ;
805
	in_token_decl = 1;
759
    decl_loc = preproc_loc ;
806
	decl_loc = preproc_loc;
760
    t = parse_pragma ( q, tendra ) ;
807
	t = parse_pragma(q, tendra);
761
    in_token_decl = 0 ;
808
	in_token_decl = 0;
762
    return ( t ) ;
809
	return(t);
763
}
810
}
764
 
811
 
765
 
812
 
766
/*
813
/*
767
    READ A PRAGMA TENDRA STATEMENT
814
    READ A PRAGMA TENDRA STATEMENT
768
 
815
 
769
    This routine processes a '#pragma TenDRA' statement, returning the
816
    This routine processes a '#pragma TenDRA' statement, returning the
770
    corresponding lexical token.  One or two tokens from the line will
817
    corresponding lexical token.  One or two tokens from the line will
771
    have already been read into p.  tendra is as in parse_pragma.
818
    have already been read into p.  tendra is as in parse_pragma.
772
*/
819
*/
773
 
820
 
774
static int read_tendra
821
static int
775
    PROTO_N ( ( p, tendra ) )
-
 
776
    PROTO_T ( PPTOKEN *p X int tendra )
-
 
777
{
-
 
778
    /* Read and macro expand the rest of the line */
-
 
779
    PPTOKEN *q = p ;
-
 
780
    while ( q->next ) q = q->next ;
-
 
781
    if ( q->tok != lex_newline ) {
-
 
782
	PPTOKEN *r = read_line ( lex_ignore_token, lex_newline ) ;
-
 
783
	if ( r ) r->pp_space = WHITE_SPACE ;
-
 
784
	q->next = r ;
-
 
785
    }
-
 
786
    q = expand_tok_list ( p ) ;
-
 
787
    free_tok_list ( p ) ;
-
 
788
    p = q ;
-
 
789
 
-
 
790
    /* Replace any identifiers by keywords */
-
 
791
    for ( q = p ; q != NULL ; q = q->next ) {
-
 
792
	int t = q->tok ;
-
 
793
	if ( t == lex_identifier ) {
-
 
794
	    t = find_hashid ( q->pp_data.id.hash ) ;
-
 
795
	    q->tok = t ;
-
 
796
	}
-
 
797
    }
-
 
798
 
-
 
799
    /* Parse the line */
-
 
800
    return ( parse_pragma ( p, tendra ) ) ;
-
 
801
}
-
 
802
 
-
 
803
 
-
 
804
/*
-
 
805
    READ A PRAGMA INTERFACE STATEMENT
-
 
806
 
-
 
807
    This routine processes a '#pragma interface' statement, returning the
-
 
808
    corresponding lexical token.  One or two tokens from the line will
-
 
809
    have already been read into p.  tendra is as in parse_pragma.
-
 
810
*/
-
 
811
 
-
 
812
static int read_interface
-
 
813
    PROTO_N ( ( p, tendra ) )
-
 
814
    PROTO_T ( PPTOKEN *p X int tendra )
822
read_tendra(PPTOKEN *p, int tendra)
815
{
823
{
816
    /* Read and macro expand the rest of the line */
824
	/* Read and macro expand the rest of the line */
817
    int tok ;
-
 
818
    int nl = 0 ;
-
 
819
    PPTOKEN *q = p ;
825
	PPTOKEN *q = p;
820
    PPTOKEN *r = p ;
-
 
821
    while ( q->next ) q = q->next ;
-
 
822
    if ( q->tok != lex_newline ) {
-
 
823
	PPTOKEN *s = read_line ( lex_ignore_token, lex_ignore_token ) ;
-
 
824
	if ( s ) s->pp_space = WHITE_SPACE ;
-
 
825
	q->next = s ;
826
	while (q->next) {
826
	nl = 1 ;
-
 
827
    }
-
 
828
    for ( q = p ; q != NULL ; q = q->next ) {
-
 
829
	/* Suppress expansion of 'TAG' */
-
 
830
	int t = q->tok ;
827
		q = q->next;
831
	if ( t == lex_identifier ) {
-
 
832
	    t = find_hashid ( q->pp_data.id.hash ) ;
-
 
833
	    if ( t == lex_tag_Hcap ) q->tok = t ;
-
 
834
	} else if ( t == lex_hash_H1 || t == lex_hash_H2 ) {
-
 
835
	    r = quote_token_name ( q ) ;
-
 
836
	    break ;
-
 
837
	}
828
	}
-
 
829
	if (q->tok != lex_newline) {
-
 
830
		PPTOKEN *r = read_line(lex_ignore_token, lex_newline);
838
	r = q ;
831
		if (r) {
-
 
832
			r->pp_space = WHITE_SPACE;
-
 
833
		}
-
 
834
		q->next = r;
-
 
835
	}
-
 
836
	q = expand_tok_list(p);
-
 
837
	free_tok_list(p);
839
    }
838
	p = q;
840
 
839
 
841
    /* Add newline token */
840
	/* Replace any identifiers by keywords */
842
    if ( nl ) {
841
	for (q = p; q != NULL; q = q->next) {
843
	while ( r->next ) r = r->next ;
842
		int t = q->tok;
844
	r->next = new_pptok () ;
843
		if (t == lex_identifier) {
845
	r->next->tok = lex_newline ;
844
			t = find_hashid(q->pp_data.id.hash);
846
	r->next->next = NULL ;
845
			q->tok = t;
847
    }
846
		}
-
 
847
	}
848
 
848
 
849
    /* Parse the line */
849
	/* Parse the line */
850
    tok = parse_pragma ( p, tendra ) ;
850
	return(parse_pragma(p, tendra));
851
    return ( tok ) ;
-
 
852
}
851
}
-
 
852
 
-
 
853
 
-
 
854
/*
-
 
855
    READ A PRAGMA INTERFACE STATEMENT
-
 
856
 
-
 
857
    This routine processes a '#pragma interface' statement, returning the
-
 
858
    corresponding lexical token.  One or two tokens from the line will
-
 
859
    have already been read into p.  tendra is as in parse_pragma.
-
 
860
*/
-
 
861
 
-
 
862
static int
-
 
863
read_interface(PPTOKEN *p, int tendra)
-
 
864
{
-
 
865
	/* Read and macro expand the rest of the line */
-
 
866
	int tok;
-
 
867
	int nl = 0;
-
 
868
	PPTOKEN *q = p;
-
 
869
	PPTOKEN *r = p;
-
 
870
	while (q->next)q = q->next;
-
 
871
	if (q->tok != lex_newline) {
-
 
872
		PPTOKEN *s = read_line(lex_ignore_token, lex_ignore_token);
-
 
873
		if (s) {
-
 
874
			s->pp_space = WHITE_SPACE;
-
 
875
		}
-
 
876
		q->next = s;
-
 
877
		nl = 1;
-
 
878
	}
-
 
879
	for (q = p; q != NULL; q = q->next) {
-
 
880
		/* Suppress expansion of 'TAG' */
-
 
881
		int t = q->tok;
-
 
882
		if (t == lex_identifier) {
-
 
883
			t = find_hashid(q->pp_data.id.hash);
-
 
884
			if (t == lex_tag_Hcap) {
-
 
885
				q->tok = t;
-
 
886
			}
-
 
887
		} else if (t == lex_hash_H1 || t == lex_hash_H2) {
-
 
888
			r = quote_token_name(q);
-
 
889
			break;
-
 
890
		}
-
 
891
		r = q;
-
 
892
	}
-
 
893
 
-
 
894
	/* Add newline token */
-
 
895
	if (nl) {
-
 
896
		while (r->next)r = r->next;
-
 
897
		r->next = new_pptok();
-
 
898
		r->next->tok = lex_newline;
-
 
899
		r->next->next = NULL;
-
 
900
	}
-
 
901
 
-
 
902
	/* Parse the line */
-
 
903
	tok = parse_pragma(p, tendra);
-
 
904
	return(tok);
-
 
905
}
853
 
906
 
854
 
907
 
855
/*
908
/*
856
    PROCESS A NON-TENDRA PRAGMA STATEMENT
909
    PROCESS A NON-TENDRA PRAGMA STATEMENT
857
 
910
 
858
    This routine processes a '#pragma' statement in which there is no
911
    This routine processes a '#pragma' statement in which there is no
Line 872... Line 925...
872
	promote				TenDRA promoted
925
	promote				TenDRA promoted
873
	compute promote			TenDRA compute promote (?)
926
	compute promote			TenDRA compute promote (?)
874
	integer literal			TenDRA integer literal
927
	integer literal			TenDRA integer literal
875
	external volatile		TenDRA external volatile
928
	external volatile		TenDRA external volatile
876
	DEFINE MEMBER			TenDRA member definition
929
	DEFINE MEMBER			TenDRA member definition
1084
 
1127
 
1085
 
1128
 
1086
/*
1129
/*
1087
    PROCESS A PRAGMA STATEMENT
1130
    PROCESS A PRAGMA STATEMENT
1088
 
1131
 
1089
    This routine analyses a '#pragma' statement, returning the corresponding
1132
    This routine analyses a '#pragma' statement, returning the corresponding
1090
    lexical token.  It is called from read_preproc_dir (q.v.) immediately
1133
    lexical token.  It is called from read_preproc_dir (q.v.) immediately
1091
    after the '#pragma' directive has been identified.  It is not called for
1134
    after the '#pragma' directive has been identified.  It is not called for
1092
    skipped '#pragma' directives.  The calling routine will skip to the end
1135
    skipped '#pragma' directives.  The calling routine will skip to the end
1093
    of the preprocessing directive if necessary.
1136
    of the preprocessing directive if necessary.
1094
*/
1137
*/
1095
 
1138
 
1096
int read_pragma
1139
int
1097
    PROTO_Z ()
1140
read_pragma(void)
1098
{
1141
{
1099
    int t ;
1142
	int t;
1100
    PPTOKEN *p = get_token () ;
1143
	PPTOKEN *p = get_token();
1101
    if ( p->tok == lex_identifier ) {
1144
	if (p->tok == lex_identifier) {
1102
	t = find_hashid ( p->pp_data.id.hash ) ;
1145
		t = find_hashid(p->pp_data.id.hash);
1103
	switch ( t ) {
1146
		switch (t) {
1104
 
1147
 
1105
	    case lex_tendra : {
1148
		case lex_tendra: {
1106
		/* Deal with '#pragma TenDRA' */
1149
			/* Deal with '#pragma TenDRA' */
1107
		int tendra = 1 ;
1150
			int tendra = 1;
1108
		p->next = free_tokens ;
1151
			p->next = free_tokens;
1109
		free_tokens = p ;
1152
			free_tokens = p;
1110
		p = get_token () ;
1153
			p = get_token();
1111
		if ( p->tok == lex_plus_Hplus ) {
1154
			if (p->tok == lex_plus_Hplus) {
1112
		    /* Allow for TenDRA++ */
1155
				/* Allow for TenDRA++ */
1113
#if LANGUAGE_CPP
1156
#if LANGUAGE_CPP
1114
		    p->next = free_tokens ;
1157
				p->next = free_tokens;
1115
		    free_tokens = p ;
1158
				free_tokens = p;
1116
		    p = get_token () ;
1159
				p = get_token();
1117
		    tendra = 2 ;
1160
				tendra = 2;
1118
#else
1161
#else
1119
		    return ( lex_ignore_token ) ;
1162
				return(lex_ignore_token);
1120
#endif
1163
#endif
1121
		}
1164
			}
1122
 
1165
 
1123
		/* Allow for optional TenDRA pragmas */
1166
			/* Allow for optional TenDRA pragmas */
1124
		t = read_non_tendra ( p, tendra ) ;
1167
			t = read_non_tendra(p, tendra);
1125
		if ( t != lex_unknown ) return ( t ) ;
1168
			if (t != lex_unknown) {
-
 
1169
				return(t);
-
 
1170
			}
1126
 
1171
 
1127
		/* Deal with TenDRA pragmas */
1172
			/* Deal with TenDRA pragmas */
1128
		t = read_tendra ( p, tendra ) ;
1173
			t = read_tendra(p, tendra);
1129
		return ( t ) ;
1174
			return(t);
1130
	    }
1175
		}
1131
 
1176
 
1132
	    case lex_ident : {
1177
		case lex_ident:
1133
		/* Deal with '#pragma ident' */
1178
			/* Deal with '#pragma ident' */
1134
		if ( !option ( OPT_ppdir_ident_ignore ) ) {
1179
			if (!option(OPT_ppdir_ident_ignore)) {
1135
		    read_ident ( lex_pragma ) ;
1180
				read_ident(lex_pragma);
1136
		}
1181
			}
1137
		return ( lex_ignore_token ) ;
1182
			return(lex_ignore_token);
1138
	    }
-
 
1139
 
1183
 
1140
	    case lex_weak : {
1184
		case lex_weak:
1141
		/* Deal with '#pragma weak' */
1185
			/* Deal with '#pragma weak' */
1142
		if ( !option ( OPT_ppdir_weak_ignore ) ) {
1186
			if (!option(OPT_ppdir_weak_ignore)) {
1143
		    read_weak ( lex_pragma ) ;
1187
				read_weak(lex_pragma);
1144
		}
1188
			}
1145
		return ( lex_ignore_token ) ;
1189
			return(lex_ignore_token);
1146
	    }
1190
		}
1147
	}
1191
	}
1148
    }
-
 
1149
 
1192
 
1150
    /* Deal with non-TenDRA pragmas */
1193
	/* Deal with non-TenDRA pragmas */
1151
    t = read_non_tendra ( p, 0 ) ;
1194
	t = read_non_tendra(p, 0);
1152
    if ( t != lex_unknown ) return ( t ) ;
1195
	if (t != lex_unknown) {
-
 
1196
		return(t);
-
 
1197
	}
1153
 
1198
 
1154
    /* Report unknown pragmas */
1199
	/* Report unknown pragmas */
1155
    free_tok_list ( p ) ;
1200
	free_tok_list(p);
1156
    report ( preproc_loc, ERR_cpp_pragma_unknown ( lex_pragma ) ) ;
1201
	report(preproc_loc, ERR_cpp_pragma_unknown(lex_pragma));
1157
    return ( lex_ignore_token ) ;
1202
	return(lex_ignore_token);
1158
}
1203
}
1159
 
1204
 
1160
 
1205
 
1161
/*
1206
/*
1162
    ANALYSE A LINT COMMENT
1207
    ANALYSE A LINT COMMENT
Line 1167... Line 1212...
1167
    approach should be used.  Other fairly standard lint comments include
1212
    approach should be used.  Other fairly standard lint comments include
1168
    VARARGS, LINTLIBRARY, CONSTANTCONDITION (CONSTCOND), EMPTY, LINTED,
1213
    VARARGS, LINTLIBRARY, CONSTANTCONDITION (CONSTCOND), EMPTY, LINTED,
1169
    PROTOLIB, PRINTFLIKE and SCANFLIKE.
1214
    PROTOLIB, PRINTFLIKE and SCANFLIKE.
1170
*/
1215
*/
1171
 
1216
 
1172
int lint_comment
1217
int
1173
    PROTO_Z ()
1218
lint_comment(void)
1174
{
1219
{
1175
    string t ;
1220
	string t;
1176
    size_t sz ;
1221
	size_t sz;
1177
    character c ;
1222
	character c;
1178
    string s = token_buff.start ;
1223
	string s = token_buff.start;
1179
    while ( c = *s, is_white_char ( ( unsigned long ) c ) ) {
1224
	while (c = *s, is_white_char((unsigned long)c)) {
1180
	/* Step over initial white space */
1225
		/* Step over initial white space */
1181
	s++ ;
-
 
1182
    }
-
 
1183
    t = s ;
-
 
1184
    while ( c = *s, is_alpha_char ( ( unsigned long ) c ) ) {
-
 
1185
	/* Scan to end of identifier */
-
 
1186
	s++ ;
1226
		s++;
1187
    }
-
 
1188
 
-
 
1189
    /* Check identifier */
-
 
1190
    sz = ( size_t ) ( s - t ) ;
-
 
1191
    switch ( sz ) {
-
 
1192
	case 8 : {
-
 
1193
	    if ( strncmp ( strlit ( t ), "ARGSUSED", sz ) == 0 ) {
-
 
1194
		/* Indicate unused variables */
-
 
1195
		suppress_variable = 1 ;
-
 
1196
	    } else if ( strncmp ( strlit ( t ), "FALLTHRU", sz ) == 0 ) {
-
 
1197
		/* Suppress fall through errors */
-
 
1198
		suppress_fall = 1 ;
-
 
1199
	    }
-
 
1200
	    break ;
-
 
1201
	}
-
 
1202
	case 10 : {
-
 
1203
	    if ( strncmp ( strlit ( t ), "NOTREACHED", sz ) == 0 ) {
-
 
1204
		/* Suppress unreached code errors */
-
 
1205
		unreached_last = 1 ;
-
 
1206
	    }
-
 
1207
	    break ;
-
 
1208
	}
1227
	}
-
 
1228
	t = s;
-
 
1229
	while (c = *s, is_alpha_char((unsigned long)c)) {
-
 
1230
		/* Scan to end of identifier */
-
 
1231
		s++;
-
 
1232
	}
-
 
1233
 
-
 
1234
	/* Check identifier */
-
 
1235
	sz = (size_t)(s - t);
-
 
1236
	switch (sz) {
-
 
1237
	case 8:
-
 
1238
		if (strncmp(strlit(t), "ARGSUSED", sz) == 0) {
-
 
1239
			/* Indicate unused variables */
-
 
1240
			suppress_variable = 1;
-
 
1241
		} else if (strncmp(strlit(t), "FALLTHRU", sz) == 0) {
-
 
1242
			/* Suppress fall through errors */
-
 
1243
			suppress_fall = 1;
-
 
1244
		}
-
 
1245
		break;
-
 
1246
	case 10:
-
 
1247
		if (strncmp(strlit(t), "NOTREACHED", sz) == 0) {
-
 
1248
			/* Suppress unreached code errors */
-
 
1249
			unreached_last = 1;
-
 
1250
		}
-
 
1251
		break;
1209
	case 11 : {
1252
	case 11:
1210
	    if ( strncmp ( strlit ( t ), "FALLTHROUGH", sz ) == 0 ) {
1253
		if (strncmp(strlit(t), "FALLTHROUGH", sz) == 0) {
1211
		/* Suppress fall through errors */
1254
			/* Suppress fall through errors */
1212
		suppress_fall = 1 ;
1255
			suppress_fall = 1;
1213
	    }
1256
		}
1214
	    break ;
1257
		break;
1215
	}
1258
	}
1216
    }
-
 
1217
 
1259
 
1218
    /* Rest of comment is ignored */
1260
	/* Rest of comment is ignored */
1219
    return ( lex_ignore_token ) ;
1261
	return(lex_ignore_token);
1220
}
1262
}