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 – /branches/tendra5/src/producers/common/parse/macro.c – Rev 5 and 6

Subversion Repositories tendra.SVN

Rev

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

Rev 5 Rev 6
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 60... Line 90...
60
    LIST OF FREE LEXICAL TOKENS
90
    LIST OF FREE LEXICAL TOKENS
61
 
91
 
62
    All the free lexical tokens are formed into a list.
92
    All the free lexical tokens are formed into a list.
63
*/
93
*/
64
 
94
 
65
PPTOKEN *free_tokens = NULL ;
95
PPTOKEN *free_tokens = NULL;
66
static LIST ( PPTOKEN_P ) alloc_tokens = NULL_list ( PPTOKEN_P ) ;
96
static LIST(PPTOKEN_P)alloc_tokens = NULL_list(PPTOKEN_P);
67
 
97
 
68
 
98
 
69
/*
99
/*
70
    ALLOCATE A NEW TOKEN
100
    ALLOCATE A NEW TOKEN
71
 
101
 
72
    This routine allocates a new token from the list free_tokens.
102
    This routine allocates a new token from the list free_tokens.
73
*/
103
*/
74
 
104
 
75
PPTOKEN *new_pptok
105
PPTOKEN *
76
    PROTO_Z ()
106
new_pptok(void)
77
{
107
{
78
    PPTOKEN *p = free_tokens ;
108
	PPTOKEN *p = free_tokens;
79
    if ( p == NULL ) {
109
	if (p == NULL) {
80
	PPTOKEN *q ;
110
		PPTOKEN *q;
81
	int i, n = 2000 ;
111
		int i, n = 2000;
82
	p = xmalloc_nof ( PPTOKEN, n ) ;
112
		p = xmalloc_nof(PPTOKEN, n);
83
	CONS_pptok ( p, alloc_tokens, alloc_tokens ) ;
113
		CONS_pptok(p, alloc_tokens, alloc_tokens);
84
	q = p ;
114
		q = p;
85
	for ( i = 1 ; i < n ; i++ ) {
115
		for (i = 1; i < n; i++) {
86
	    q->next = q + 1 ;
116
			q->next = q + 1;
87
	    q++ ;
117
			q++;
88
	}
118
		}
89
	q->next = NULL ;
119
		q->next = NULL;
90
    }
120
	}
91
    free_tokens = p->next ;
121
	free_tokens = p->next;
92
    p->pp_opts = real_opts ;
122
	p->pp_opts = real_opts;
93
    return ( p ) ;
123
	return(p);
94
}
124
}
95
 
125
 
96
 
126
 
97
/*
127
/*
98
    FREE A SINGLE TOKEN
128
    FREE A SINGLE TOKEN
99
 
129
 
100
    This macro frees the single token P by adding it to the list of all
130
    This macro frees the single token P by adding it to the list of all
101
    free tokens.
131
    free tokens.
102
*/
132
*/
103
 
133
 
104
#define free_pptok( P )\
134
#define free_pptok(P)			\
105
    {\
135
    {					\
106
	( P )->next = free_tokens ;\
136
	(P)->next = free_tokens;	\
107
	free_tokens = ( P ) ;\
137
	free_tokens = (P);		\
108
    }
138
    }
109
 
139
 
110
 
140
 
111
/*
141
/*
112
    FREE A LIST OF TOKENS
142
    FREE A LIST OF TOKENS
113
 
143
 
114
    This routine adds the list of tokens p to the list of all free tokens.
144
    This routine adds the list of tokens p to the list of all free tokens.
115
*/
145
*/
116
 
146
 
117
void free_tok_list
147
void
118
    PROTO_N ( ( p ) )
-
 
119
    PROTO_T ( PPTOKEN *p )
148
free_tok_list(PPTOKEN *p)
120
{
149
{
121
    PPTOKEN *q = p ;
150
	PPTOKEN *q = p;
122
    if ( q == NULL ) return ;
151
	if (q == NULL) {
-
 
152
		return;
-
 
153
	}
123
    while ( q->next ) q = q->next ;
154
	while (q->next) {
-
 
155
		q = q->next;
-
 
156
	}
124
    q->next = free_tokens ;
157
	q->next = free_tokens;
125
    free_tokens = p ;
158
	free_tokens = p;
126
    return ;
159
	return;
127
}
160
}
128
 
161
 
129
 
162
 
130
/*
163
/*
131
    FREE ALL ALLOCATED PREPROCESSING TOKENS
164
    FREE ALL ALLOCATED PREPROCESSING TOKENS
132
 
165
 
133
    This routine frees all the space allocated for preprocessing tokens.
166
    This routine frees all the space allocated for preprocessing tokens.
134
    It should only be called after the input has been completely processed.
167
    It should only be called after the input has been completely processed.
135
*/
168
*/
136
 
169
 
137
void term_macros
170
void
138
    PROTO_Z ()
171
term_macros(void)
139
{
172
{
140
    LIST ( PPTOKEN_P ) p = alloc_tokens ;
173
	LIST(PPTOKEN_P)p = alloc_tokens;
141
    while ( !IS_NULL_list ( p ) ) {
174
	while (!IS_NULL_list(p)) {
142
	PPTOKEN *q ;
175
		PPTOKEN *q;
143
	DESTROY_CONS_pptok ( destroy, q, p, p ) ;
176
		DESTROY_CONS_pptok(destroy, q, p, p);
144
	xfree_nof ( q ) ;
177
		xfree_nof(q);
145
    }
178
	}
146
    alloc_tokens = p ;
179
	alloc_tokens = p;
147
    free_tokens = NULL ;
180
	free_tokens = NULL;
148
    return ;
181
	return;
149
}
182
}
150
 
183
 
151
 
184
 
152
/*
185
/*
153
    COPY A TOKEN
186
    COPY A TOKEN
154
 
187
 
155
    This macro copies the contents of the token with token value T and data
188
    This macro copies the contents of the token with token value T and data
156
    Q into P.
189
    Q into P.
157
*/
190
*/
158
 
191
 
159
#define copy_pptok( P, T, Q )\
192
#define copy_pptok(P, T, Q)		\
160
    {\
193
    {					\
161
	( P )->tok = ( T ) ;\
194
	(P)->tok = (T);			\
162
	( P )->pp_data = ( Q )->pp_data ;\
195
	(P)->pp_data = (Q)->pp_data;	\
163
	( P )->pp_opts = ( Q )->pp_opts ;\
196
	(P)->pp_opts = (Q)->pp_opts;	\
164
	( P )->pp_space = ( Q )->pp_space ;\
197
	(P)->pp_space = (Q)->pp_space;	\
165
    }
198
    }
166
 
199
 
167
 
200
 
168
/*
201
/*
169
    ASSIGN TOKEN COMPONENTS
202
    ASSIGN TOKEN COMPONENTS
Line 174... Line 207...
174
    less than or equal to LAST_COMPLEX_TOKEN (defined in symbols.h).  If any
207
    less than or equal to LAST_COMPLEX_TOKEN (defined in symbols.h).  If any
175
    cases are added to this routine then it may be necessary to change the
208
    cases are added to this routine then it may be necessary to change the
176
    value of this macro.
209
    value of this macro.
177
*/
210
*/
178
 
211
 
179
void token_parts
212
void
180
    PROTO_N ( ( t, p ) )
-
 
181
    PROTO_T ( int t X PPTOKEN *p )
213
token_parts(int t, PPTOKEN *p)
182
{
214
{
183
    switch ( t ) {
215
	switch (t) {
184
	case lex_identifier : {
216
	case lex_identifier: {
185
	    /* Identifiers */
217
		/* Identifiers */
186
	    HASHID nm = token_hashid ;
218
		HASHID nm = token_hashid;
187
	    IDENTIFIER id = DEREF_id ( hashid_id ( nm ) ) ;
219
		IDENTIFIER id = DEREF_id(hashid_id(nm));
188
	    p->pp_data.id.hash = nm ;
220
		p->pp_data.id.hash = nm;
189
	    p->pp_data.id.use = id ;
221
		p->pp_data.id.use = id;
190
	    break ;
222
		break;
191
	}
223
	}
192
	case lex_char_Hlit :
224
	case lex_char_Hlit:
193
	case lex_string_Hlit :
225
	case lex_string_Hlit:
194
	case lex_wchar_Hlit :
226
	case lex_wchar_Hlit:
195
	case lex_wstring_Hlit : {
227
	case lex_wstring_Hlit: {
196
	    /* String and character literals */
228
		/* String and character literals */
197
	    string s1 = token_buff.start ;
229
		string s1 = token_buff.start;
198
	    gen_size n = ( gen_size ) ( token_buff.posn - s1 ) ;
230
		gen_size n = (gen_size)(token_buff.posn - s1);
199
	    string s2 ;
231
		string s2;
200
	    if ( n < 2 ) {
232
		if (n < 2) {
201
		/* Optimise for small strings */
233
			/* Optimise for small strings */
202
		s2 = xustrcpy ( s1 ) ;
234
			s2 = xustrcpy(s1);
203
	    } else {
235
		} else {
204
		s2 = xustr ( n + 1 ) ;
236
			s2 = xustr(n + 1);
205
		xumemcpy ( s2, s1, n ) ;
237
			xumemcpy(s2, s1, n);
206
		s2 [n] = 0 ;
238
			s2[n] = 0;
207
	    }
239
		}
208
	    p->pp_data.str.start = s2 ;
240
		p->pp_data.str.start = s2;
209
	    p->pp_data.str.end = s2 + n ;
241
		p->pp_data.str.end = s2 + n;
210
	    break ;
242
		break;
211
	}
243
	}
212
	case lex_integer_Hlit : {
244
	case lex_integer_Hlit:
213
	    /* Integer and floating-point literals */
245
		/* Integer and floating-point literals */
214
	    p->pp_data.text = xustrcpy ( token_buff.start ) ;
246
		p->pp_data.text = xustrcpy(token_buff.start);
215
	    break ;
247
		break;
216
	}
-
 
217
	case lex_hash_Hif :
248
	case lex_hash_Hif:
218
	case lex_hash_Helif : {
249
	case lex_hash_Helif:
219
	    /* Target dependent conditionals */
250
		/* Target dependent conditionals */
220
	    p->pp_data.exp = crt_hash_if_exp ;
251
		p->pp_data.exp = crt_hash_if_exp;
221
	    break ;
252
		break;
222
	}
-
 
223
	case lex_unknown : {
253
	case lex_unknown: {
224
	    /* Unknown characters */
254
		/* Unknown characters */
225
	    int i ;
255
		int i;
226
	    string s1 = token_buff.start ;
256
		string s1 = token_buff.start;
227
	    string s2 = p->pp_data.buff ;
257
		string s2 = p->pp_data.buff;
228
	    ASSERT ( MULTI_WIDTH <= sizeof ( p->pp_data.buff ) ) ;
258
		ASSERT(MULTI_WIDTH <= sizeof(p->pp_data.buff));
229
	    for ( i = 0 ; i < MULTI_WIDTH ; i++ ) s2 [i] = s1 [i] ;
259
		for (i = 0; i < MULTI_WIDTH; i++)s2[i] = s1[i];
230
	    break ;
260
		break;
231
	}
261
	}
232
    }
262
	}
233
    return ;
263
	return;
234
}
264
}
235
 
265
 
236
 
266
 
237
/*
267
/*
238
    REMOVE ANY IGNORED TOKENS FROM A LIST
268
    REMOVE ANY IGNORED TOKENS FROM A LIST
239
 
269
 
240
    This routine removes any ignored tokens from the list tok, returning
270
    This routine removes any ignored tokens from the list tok, returning
241
    the result.
271
    the result.
242
*/
272
*/
243
 
273
 
244
PPTOKEN *clean_tok_list
274
PPTOKEN *
245
    PROTO_N ( ( toks ) )
-
 
246
    PROTO_T ( PPTOKEN *toks )
275
clean_tok_list(PPTOKEN *toks)
247
{
276
{
248
    unsigned long sp = 0 ;
277
	unsigned long sp = 0;
249
    PPTOKEN p0, *p = &p0 ;
278
	PPTOKEN p0, *p = &p0;
250
    PPTOKEN *q ;
279
	PPTOKEN *q;
251
    p->next = toks ;
280
	p->next = toks;
252
    while ( q = p->next, q != NULL ) {
281
	while (q = p->next, q != NULL) {
253
	if ( q->tok == lex_ignore_token ) {
282
		if (q->tok == lex_ignore_token) {
254
	    sp |= q->pp_space ;
283
			sp |= q->pp_space;
255
	    p->next = q->next ;
284
			p->next = q->next;
256
	    free_pptok ( q ) ;
285
			free_pptok(q);
257
	    q = p->next ;
286
			q = p->next;
258
	    if ( q == NULL ) break ;
287
			if (q == NULL) {
-
 
288
				break;
-
 
289
			}
259
	} else {
290
		} else {
260
	    if ( sp ) {
291
			if (sp) {
261
		q->pp_space |= sp ;
292
				q->pp_space |= sp;
262
		sp = 0 ;
293
				sp = 0;
263
	    }
294
			}
264
	}
295
		}
265
	p = q ;
296
		p = q;
266
    }
297
	}
267
    return ( p0.next ) ;
298
	return(p0.next);
268
}
299
}
269
 
300
 
270
 
301
 
271
/*
302
/*
272
    READ A LINE OF TOKENS
303
    READ A LINE OF TOKENS
273
 
304
 
274
    This routine reads the sequence of preprocessing tokens comprising a
305
    This routine reads the sequence of preprocessing tokens comprising a
275
    preprocessing directive (for example, a macro definition).  If t1 is
306
    preprocessing directive (for example, a macro definition).  If t1 is
276
    not lex_ignore_token then it is taken to be the first token in the
307
    not lex_ignore_token then it is taken to be the first token in the
277
    definition, similarly tn gives the last token.
308
    definition, similarly tn gives the last token.
278
*/
309
*/
279
 
310
 
280
PPTOKEN *read_line
311
PPTOKEN *
281
    PROTO_N ( ( t1, tn ) )
-
 
282
    PROTO_T ( int t1 X int tn )
312
read_line(int t1, int tn)
283
{
313
{
284
    int t = t1 ;
314
	int t = t1;
285
    unsigned long sp = 0 ;
315
	unsigned long sp = 0;
286
    PPTOKEN dummy_tok, *this_tok = &dummy_tok ;
316
	PPTOKEN dummy_tok, *this_tok = &dummy_tok;
287
    if ( t == lex_ignore_token ) {
317
	if (t == lex_ignore_token) {
288
	t = read_token () ;
318
		t = read_token();
289
	update_column () ;
319
		update_column();
-
 
320
		if (in_preproc_dir) {
290
	if ( in_preproc_dir ) preproc_loc = crt_loc ;
321
			preproc_loc = crt_loc;
291
    }
322
		}
-
 
323
	}
292
    while ( t != lex_newline && t != lex_eof ) {
324
	while (t != lex_newline && t != lex_eof) {
293
	this_tok->next = new_pptok () ;
325
		this_tok->next = new_pptok();
294
	this_tok = this_tok->next ;
326
		this_tok = this_tok->next;
295
	this_tok->tok = t ;
327
		this_tok->tok = t;
296
	if ( t <= LAST_COMPLEX_TOKEN ) token_parts ( t, this_tok ) ;
328
		if (t <= LAST_COMPLEX_TOKEN) {
-
 
329
			token_parts(t, this_tok);
-
 
330
		}
297
	this_tok->pp_space = ( sp & WHITE_MASK ) ;
331
		this_tok->pp_space = (sp & WHITE_MASK);
298
	sp = skip_white ( 0 ) ;
332
		sp = skip_white(0);
299
	t = read_token () ;
333
		t = read_token();
300
	update_column () ;
334
		update_column();
-
 
335
		if (in_preproc_dir) {
301
	if ( in_preproc_dir ) preproc_loc = crt_loc ;
336
			preproc_loc = crt_loc;
302
    }
337
		}
-
 
338
	}
303
    if ( tn != lex_ignore_token ) {
339
	if (tn != lex_ignore_token) {
304
	this_tok->next = new_pptok () ;
340
		this_tok->next = new_pptok();
305
	this_tok = this_tok->next ;
341
		this_tok = this_tok->next;
306
	this_tok->tok = tn ;
342
		this_tok->tok = tn;
307
	token_parts ( tn, this_tok ) ;
343
		token_parts(tn, this_tok);
308
	this_tok->pp_space = ( sp & WHITE_MASK ) ;
344
		this_tok->pp_space = (sp & WHITE_MASK);
309
    }
345
	}
310
    this_tok->next = NULL ;
346
	this_tok->next = NULL;
-
 
347
	if (in_preproc_dir) {
311
    if ( in_preproc_dir ) IGNORE skip_to_end () ;
348
		IGNORE skip_to_end();
-
 
349
	}
312
    return ( dummy_tok.next ) ;
350
	return(dummy_tok.next);
313
}
351
}
314
 
352
 
315
 
353
 
316
/*
354
/*
317
    COPY A LIST OF TOKENS
355
    COPY A LIST OF TOKENS
318
 
356
 
319
    This routine copies the list of tokens toks, excluding any ignored
357
    This routine copies the list of tokens toks, excluding any ignored
320
    tokens.
358
    tokens.
321
*/
359
*/
322
 
360
 
323
static PPTOKEN *copy_tok_list
361
static PPTOKEN *
324
    PROTO_N ( ( toks ) )
-
 
325
    PROTO_T ( PPTOKEN *toks )
362
copy_tok_list(PPTOKEN *toks)
326
{
363
{
327
    PPTOKEN *ptr_tok ;
364
	PPTOKEN *ptr_tok;
328
    PPTOKEN dummy_tok, *this_tok = &dummy_tok ;
365
	PPTOKEN dummy_tok, *this_tok = &dummy_tok;
329
    for ( ptr_tok = toks ; ptr_tok != NULL ; ptr_tok = ptr_tok->next ) {
366
	for (ptr_tok = toks; ptr_tok != NULL; ptr_tok = ptr_tok->next) {
330
	int t = ptr_tok->tok ;
367
		int t = ptr_tok->tok;
331
	if ( t != lex_ignore_token ) {
368
		if (t != lex_ignore_token) {
332
	    this_tok->next = new_pptok () ;
369
			this_tok->next = new_pptok();
333
	    this_tok = this_tok->next ;
370
			this_tok = this_tok->next;
334
	    copy_pptok ( this_tok, t, ptr_tok ) ;
371
			copy_pptok(this_tok, t, ptr_tok);
-
 
372
		}
335
	}
373
	}
336
    }
-
 
337
    this_tok->next = NULL ;
374
	this_tok->next = NULL;
338
    return ( dummy_tok.next ) ;
375
	return(dummy_tok.next);
339
}
376
}
340
 
377
 
341
 
378
 
342
/*
379
/*
343
    STRINGISE A LIST OF TOKENS
380
    STRINGISE A LIST OF TOKENS
Line 349... Line 386...
349
    by a '\'.  This routine is used in the implementation of the # operator,
386
    by a '\'.  This routine is used in the implementation of the # operator,
350
    in macro #include directives and a couple of other preprocessing
387
    in macro #include directives and a couple of other preprocessing
351
    directives.  It returns 1 to indicate a valid string.
388
    directives.  It returns 1 to indicate a valid string.
352
*/
389
*/
353
 
390
 
354
int quote_tok_list
391
int
355
    PROTO_N ( ( toks, esc, quote ) )
-
 
356
    PROTO_T ( PPTOKEN *toks X int esc X int quote )
392
quote_tok_list(PPTOKEN *toks, int esc, int quote)
357
{
393
{
358
    int res = 1 ;
394
	int res = 1;
359
    string st, se ;
395
	string st, se;
360
    int started = 0 ;
396
	int started = 0;
361
    int escaped = 0 ;
397
	int escaped = 0;
362
    PPTOKEN *ptr_tok ;
398
	PPTOKEN *ptr_tok;
363
    character qo = ( character ) quote ;
399
	character qo = (character)quote;
364
    BUFFER *bf = clear_buffer ( &token_buff, NIL ( FILE ) ) ;
400
	BUFFER *bf = clear_buffer(&token_buff, NIL(FILE));
365
 
401
 
366
    /* Scan through tokens */
402
	/* Scan through tokens */
367
    for ( ptr_tok = toks ; ptr_tok != NULL ; ptr_tok = ptr_tok->next ) {
403
	for (ptr_tok = toks; ptr_tok != NULL; ptr_tok = ptr_tok->next) {
368
	character p, q ;
404
		character p, q;
369
	int t = ptr_tok->tok ;
405
		int t = ptr_tok->tok;
370
	if ( t == lex_ignore_token ) continue ;
406
		if (t == lex_ignore_token) {
-
 
407
			continue;
-
 
408
		}
-
 
409
 
-
 
410
		/* Print initial space if necessary */
-
 
411
		if (ptr_tok->pp_space && started) {
-
 
412
			bfputc(bf, char_space);
-
 
413
		}
-
 
414
 
-
 
415
		/* Find the token name */
-
 
416
		switch (t) {
-
 
417
		case lex_identifier: {
-
 
418
			/* Identifiers */
-
 
419
			HASHID nm = ptr_tok->pp_data.id.hash;
-
 
420
			st = DEREF_string(hashid_name_etc_text(nm));
-
 
421
			bfputs(bf, st);
-
 
422
			break;
-
 
423
		}
-
 
424
		case lex_integer_Hlit:
-
 
425
			/* Integer and floating-point literals */
-
 
426
			st = ptr_tok->pp_data.text;
-
 
427
			bfputs(bf, st);
-
 
428
			break;
-
 
429
		case lex_char_Hlit:
-
 
430
			/* Character literals */
-
 
431
			p = 0;
-
 
432
			q = char_single_quote;
-
 
433
string_label:
-
 
434
			st = ptr_tok->pp_data.str.start;
-
 
435
			se = ptr_tok->pp_data.str.end;
-
 
436
 
-
 
437
			/* Prefix and opening quote */
-
 
438
			if (p) {
-
 
439
				bfputc(bf, (int)p);
-
 
440
			}
-
 
441
			if (esc && q == qo) {
-
 
442
				bfputc(bf, char_backslash);
-
 
443
			}
-
 
444
			bfputc(bf, (int)q);
-
 
445
 
-
 
446
			/* Copy string */
-
 
447
			while (st != se) {
-
 
448
				character c = *(st++);
-
 
449
				if (c == qo || c == char_backslash) {
-
 
450
					/* Escaped characters */
-
 
451
					if (esc) {
-
 
452
						bfputc(bf, char_backslash);
-
 
453
					}
-
 
454
				}
-
 
455
				bfputc(bf, (int)c);
-
 
456
			}
371
 
457
 
372
	/* Print initial space if necessary */
-
 
373
	if ( ptr_tok->pp_space && started ) bfputc ( bf, char_space ) ;
-
 
374
 
-
 
375
	/* Find the token name */
-
 
376
	switch ( t ) {
-
 
377
	    case lex_identifier : {
-
 
378
		/* Identifiers */
-
 
379
		HASHID nm = ptr_tok->pp_data.id.hash ;
-
 
380
		st = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
-
 
381
		bfputs ( bf, st ) ;
-
 
382
		break ;
-
 
383
	    }
-
 
384
	    case lex_integer_Hlit : {
-
 
385
		/* Integer and floating-point literals */
-
 
386
		st = ptr_tok->pp_data.text ;
-
 
387
		bfputs ( bf, st ) ;
-
 
388
		break ;
-
 
389
	    }
-
 
390
	    case lex_char_Hlit : {
-
 
391
		/* Character literals */
-
 
392
		p = 0 ;
-
 
393
		q = char_single_quote ;
458
			/* Closing quote */
394
		string_label : {
-
 
395
		    st = ptr_tok->pp_data.str.start ;
-
 
396
		    se = ptr_tok->pp_data.str.end ;
-
 
397
 
-
 
398
		    /* Prefix and opening quote */
-
 
399
		    if ( p ) bfputc ( bf, ( int ) p ) ;
-
 
400
		    if ( esc && q == qo ) bfputc ( bf, char_backslash ) ;
-
 
401
		    bfputc ( bf, ( int ) q ) ;
-
 
402
 
-
 
403
		    /* Copy string */
-
 
404
		    while ( st != se ) {
459
			if (esc && q == qo) {
405
			character c = *( st++ ) ;
-
 
406
			if ( c == qo || c == char_backslash ) {
-
 
407
			    /* Escaped characters */
-
 
408
			    if ( esc ) bfputc ( bf, char_backslash ) ;
460
				bfputc(bf, char_backslash);
409
			}
461
			}
410
			bfputc ( bf, ( int ) c ) ;
462
			bfputc(bf, (int)q);
411
		    }
-
 
412
 
-
 
413
		    /* Closing quote */
-
 
414
		    if ( esc && q == qo ) bfputc ( bf, char_backslash ) ;
-
 
415
		    bfputc ( bf, ( int ) q ) ;
-
 
416
		}
-
 
417
		break ;
463
			break;
418
	    }
-
 
419
	    case lex_wchar_Hlit : {
464
		case lex_wchar_Hlit:
420
		/* Wide character literals */
465
			/* Wide character literals */
421
		p = char_L ;
466
			p = char_L;
422
		q = char_single_quote ;
467
			q = char_single_quote;
423
		goto string_label ;
468
			goto string_label;
424
	    }
-
 
425
	    case lex_string_Hlit : {
469
		case lex_string_Hlit:
426
		/* String literals */
470
			/* String literals */
427
		p = 0 ;
471
			p = 0;
428
		q = char_quote ;
472
			q = char_quote;
429
		goto string_label ;
473
			goto string_label;
430
	    }
-
 
431
	    case lex_wstring_Hlit : {
474
		case lex_wstring_Hlit:
432
		/* Wide string literals */
475
			/* Wide string literals */
433
		p = char_L ;
476
			p = char_L;
434
		q = char_quote ;
477
			q = char_quote;
435
		goto string_label ;
478
			goto string_label;
436
	    }
-
 
437
	    case lex_unknown : {
479
		case lex_unknown: {
438
		/* Unknown characters */
480
			/* Unknown characters */
439
		unsigned long u ;
481
			unsigned long u;
440
		int ch = CHAR_SIMPLE ;
482
			int ch = CHAR_SIMPLE;
441
		u = get_multi_char ( ptr_tok->pp_data.buff, &ch ) ;
483
			u = get_multi_char(ptr_tok->pp_data.buff, &ch);
442
		if ( ch == CHAR_SIMPLE ) {
484
			if (ch == CHAR_SIMPLE) {
443
		    bfputc ( bf, ( int ) u ) ;
485
				bfputc(bf, (int)u);
444
		} else {
486
			} else {
445
		    print_char ( u, ch, 0, bf ) ;
487
				print_char(u, ch, 0, bf);
446
		}
488
			}
447
		break ;
489
			break;
448
	    }
490
		}
449
	    case lex_macro_Harg : {
491
		case lex_macro_Harg: {
450
		/* Macro parameters */
492
			/* Macro parameters */
451
		HASHID nm = ptr_tok->pp_data.par.hash ;
493
			HASHID nm = ptr_tok->pp_data.par.hash;
452
		st = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
494
			st = DEREF_string(hashid_name_etc_text(nm));
453
		bfputs ( bf, st ) ;
495
			bfputs(bf, st);
454
		break ;
496
			break;
455
	    }
497
		}
456
	    default : {
498
		default:
457
		/* Symbols */
499
			/* Symbols */
458
		st = token_name ( t ) ;
500
			st = token_name(t);
459
		bfputs ( bf, st ) ;
501
			bfputs(bf, st);
460
		break ;
502
			break;
461
	    }
-
 
462
	}
-
 
463
	started = 1 ;
-
 
464
    }
-
 
465
 
-
 
466
    /* End of string */
-
 
467
    bfputc ( bf, 0 ) ;
-
 
468
    bf->posn-- ;
-
 
469
 
-
 
470
    /* Check for legal strings */
-
 
471
    st = bf->start ;
-
 
472
    se = bf->posn ;
-
 
473
    while ( st != se ) {
-
 
474
	if ( escaped ) {
-
 
475
	    escaped = 0 ;
-
 
476
	} else {
-
 
477
	    character c = *st ;
-
 
478
	    if ( c == qo ) res = 0 ;
-
 
479
	    if ( c == char_backslash ) escaped = 1 ;
-
 
480
	}
-
 
481
	st++ ;
-
 
482
    }
-
 
483
    if ( escaped ) res = 0 ;
-
 
484
    return ( res ) ;
-
 
485
}
-
 
486
 
-
 
487
 
-
 
488
/*
-
 
489
    CONCATENATE TWO TOKENS
-
 
490
 
-
 
491
    This routine concatenates the two tokens p and q into a single token.
-
 
492
    This is used to implement the ## operator.  If the result is a valid
-
 
493
    preprocessing token then p is overwritten by the result and 1 is
-
 
494
    returned.  Otherwise p and q are unchanged and 0 is returned.
-
 
495
*/
-
 
496
 
-
 
497
static int concat_pptoks
-
 
498
    PROTO_N ( ( p, q ) )
-
 
499
    PROTO_T ( PPTOKEN *p X PPTOKEN *q )
-
 
500
{
-
 
501
    int a = p->tok ;
-
 
502
    int b = q->tok ;
-
 
503
    unsigned long sa = p->pp_space ;
-
 
504
    unsigned long sb = q->pp_space ;
-
 
505
    p->pp_space = ( sa | sb ) ;
-
 
506
    q->pp_space = 0 ;
-
 
507
    if ( a >= FIRST_SYMBOL && a <= LAST_SYMBOL ) {
-
 
508
	if ( b >= FIRST_SYMBOL && b <= LAST_SYMBOL ) {
-
 
509
	    /* Two symbols may combine to give another symbol */
-
 
510
	    int c ;
-
 
511
	    string s = token_buff.start ;
-
 
512
	    ustrcpy_v ( s, token_name ( a ) ) ;
-
 
513
	    ustrcpy_v ( s + ustrlen ( s ), token_name ( b ) ) ;
-
 
514
	    for ( c = FIRST_SYMBOL ; c <= LAST_SYMBOL ; c++ ) {
-
 
515
		if ( ustreq ( s, token_name ( c ) ) ) {
-
 
516
		    /* Token found - check options */
-
 
517
		    p->tok = c ;
-
 
518
		    if ( c >= FIRST_C_SYMBOL && c <= LAST_C_SYMBOL ) {
-
 
519
			return ( 1 ) ;
-
 
520
		    }
-
 
521
#if LANGUAGE_CPP
-
 
522
		    if ( c >= FIRST_CPP_SYMBOL && c <= LAST_CPP_SYMBOL ) {
-
 
523
			return ( 1 ) ;
-
 
524
		    }
-
 
525
#endif
-
 
526
		    if ( c >= FIRST_EXTRA_SYMBOL && c <= LAST_EXTRA_SYMBOL ) {
-
 
527
			if ( allow_extra_symbols ) return ( 1 ) ;
-
 
528
		    }
-
 
529
		    if ( c >= FIRST_DIGRAPH && c <= LAST_DIGRAPH ) {
-
 
530
			if ( allow_digraphs ) return ( 1 ) ;
-
 
531
		    }
-
 
532
		    p->tok = a ;
-
 
533
		}
503
		}
534
	    }
-
 
535
	    return ( 0 ) ;
-
 
536
 
-
 
537
	} else if ( a == lex_dot && b == lex_integer_Hlit ) {
-
 
538
	    /* A dot may start a number */
-
 
539
	    string s = q->pp_data.text ;
-
 
540
	    if ( s [0] == char_dot ) return ( 0 ) ;
-
 
541
	    p->tok = lex_integer_Hlit ;
-
 
542
	    p->pp_data.text = xustrcat ( token_name ( a ), s ) ;
-
 
543
	    return ( 1 ) ;
504
		started = 1;
544
 
-
 
545
	} else if ( a == lex_backslash && b == lex_identifier ) {
-
 
546
	    /* A backslash may start a universal character */
-
 
547
	    /* NOT YET IMPLEMENTED */
-
 
548
	    /* EMPTY */
-
 
549
	}
505
	}
550
 
506
 
551
    } else if ( a == lex_identifier ) {
-
 
552
	HASHID nm = p->pp_data.id.hash ;
-
 
553
	string s = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
-
 
554
	if ( b == lex_identifier ) {
507
	/* End of string */
555
	    /* Two identifiers give another identifier */
-
 
556
	    HASHID nm2 = q->pp_data.id.hash ;
-
 
557
	    string s2 = DEREF_string ( hashid_name_etc_text ( nm2 ) ) ;
-
 
558
	    s = xustrcat ( s, s2 ) ;
508
	bfputc(bf, 0);
559
	    nm = lookup_name ( s, hash ( s ), 2, lex_identifier ) ;
-
 
560
	    p->pp_data.id.hash = nm ;
-
 
561
	    p->pp_data.id.use = DEREF_id ( hashid_id ( nm ) ) ;
-
 
562
	    return ( 1 ) ;
509
	bf->posn--;
563
 
510
 
564
	} else if ( b == lex_integer_Hlit ) {
511
	/* Check for legal strings */
565
	    /* An identifier and a number may give an identifier */
-
 
566
	    character c ;
512
	st = bf->start;
567
	    string n = q->pp_data.text ;
513
	se = bf->posn;
568
	    while ( c = *( n++ ), c != 0 ) {
514
	while (st != se) {
569
		if ( c == char_dot || c == char_plus || c == char_minus ) {
-
 
570
		    /* The number must be entirely alphanumeric */
-
 
571
		    return ( 0 ) ;
515
		if (escaped) {
572
		}
516
			escaped = 0;
573
	    }
517
		} else {
574
	    s = xustrcat ( s, q->pp_data.text ) ;
518
			character c = *st;
575
	    nm = lookup_name ( s, hash ( s ), 2, lex_identifier ) ;
-
 
576
	    p->pp_data.id.hash = nm ;
519
			if (c == qo) {
577
	    p->pp_data.id.use = DEREF_id ( hashid_id ( nm ) ) ;
-
 
578
	    return ( 1 ) ;
520
				res = 0;
579
 
521
			}
580
	} else if ( s [0] == char_L && s [1] == 0 ) {
-
 
581
	    /* An L may start a wide character or string */
-
 
582
	    if ( b == lex_char_Hlit ) {
522
			if (c == char_backslash) {
583
		p->tok = lex_wchar_Hlit ;
523
				escaped = 1;
584
		p->pp_data.str.start = q->pp_data.str.start ;
-
 
585
		p->pp_data.str.end = q->pp_data.str.end ;
-
 
586
		return ( 1 ) ;
524
			}
587
	    } else if ( b == lex_string_Hlit ) {
-
 
-
 
525
		}
588
		p->tok = lex_wstring_Hlit ;
526
		st++;
589
		p->pp_data.str.start = q->pp_data.str.start ;
-
 
590
		p->pp_data.str.end = q->pp_data.str.end ;
-
 
-
 
527
	}
591
		return ( 1 ) ;
528
	if (escaped) {
592
	    }
529
		res = 0;
593
	}
530
	}
-
 
531
	return(res);
-
 
532
}
594
 
533
 
595
    } else if ( a == lex_integer_Hlit ) {
-
 
596
	string s = p->pp_data.text ;
-
 
597
	if ( b == lex_identifier ) {
-
 
598
	    /* A number followed by an identifier is a number */
-
 
599
	    HASHID nm = q->pp_data.id.hash ;
-
 
600
	    string s2 = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
-
 
601
	    p->pp_data.text = xustrcat ( s, s2 ) ;
-
 
602
	    return ( 1 ) ;
-
 
603
 
-
 
604
	} else if ( b == lex_integer_Hlit ) {
-
 
605
	    /* Two numbers form another number */
-
 
606
	    string s2 = q->pp_data.text ;
-
 
607
	    p->pp_data.text = xustrcat ( s, s2 ) ;
-
 
608
	    return ( 1 ) ;
-
 
609
 
-
 
610
	} else if ( b == lex_dot || b == lex_ellipsis ) {
-
 
611
	    /* A number followed by a sequence of dots is a number */
-
 
612
	    p->pp_data.text = xustrcat ( s, token_name ( b ) ) ;
-
 
613
	    return ( 1 ) ;
-
 
614
 
-
 
615
	} else if ( b == lex_plus || b == lex_minus ) {
-
 
616
	    /* A sign may terminate a number after e or E */
-
 
617
	    unsigned n = ( unsigned ) ustrlen ( s ) - 1 ;
-
 
618
	    if ( s [n] == char_e || s [n] == char_E ) {
-
 
619
		p->pp_data.text = xustrcat ( s, token_name ( b ) ) ;
-
 
620
		return ( 1 ) ;
-
 
621
	    }
-
 
622
	}
-
 
623
    }
-
 
624
    return ( 0 ) ;
-
 
625
}
-
 
626
 
534
 
-
 
535
/*
-
 
536
    CONCATENATE TWO TOKENS
627
 
537
 
-
 
538
    This routine concatenates the two tokens p and q into a single token.
-
 
539
    This is used to implement the ## operator.  If the result is a valid
-
 
540
    preprocessing token then p is overwritten by the result and 1 is
-
 
541
    returned.  Otherwise p and q are unchanged and 0 is returned.
-
 
542
*/
-
 
543
 
-
 
544
static int
-
 
545
concat_pptoks(PPTOKEN *p, PPTOKEN *q)
-
 
546
{
-
 
547
	int a = p->tok;
-
 
548
	int b = q->tok;
-
 
549
	unsigned long sa = p->pp_space;
-
 
550
	unsigned long sb = q->pp_space;
-
 
551
	p->pp_space = (sa | sb);
-
 
552
	q->pp_space = 0;
-
 
553
	if (a >= FIRST_SYMBOL && a <= LAST_SYMBOL) {
-
 
554
		if (b >= FIRST_SYMBOL && b <= LAST_SYMBOL) {
-
 
555
			/* Two symbols may combine to give another symbol */
-
 
556
			int c;
-
 
557
			string s = token_buff.start;
-
 
558
			ustrcpy_v(s, token_name(a));
-
 
559
			ustrcpy_v(s + ustrlen(s), token_name(b));
-
 
560
			for (c = FIRST_SYMBOL; c <= LAST_SYMBOL; c++) {
-
 
561
				if (ustreq(s, token_name(c))) {
-
 
562
					/* Token found - check options */
-
 
563
					p->tok = c;
-
 
564
					if (c >= FIRST_C_SYMBOL &&
-
 
565
					    c <= LAST_C_SYMBOL) {
-
 
566
						return(1);
-
 
567
					}
-
 
568
#if LANGUAGE_CPP
-
 
569
					if (c >= FIRST_CPP_SYMBOL &&
-
 
570
					    c <= LAST_CPP_SYMBOL) {
-
 
571
						return(1);
-
 
572
					}
-
 
573
#endif
-
 
574
					if (c >= FIRST_EXTRA_SYMBOL &&
-
 
575
					    c <= LAST_EXTRA_SYMBOL) {
-
 
576
						if (allow_extra_symbols) {
-
 
577
							return(1);
-
 
578
						}
-
 
579
					}
-
 
580
					if (c >= FIRST_DIGRAPH &&
-
 
581
					    c <= LAST_DIGRAPH) {
-
 
582
						if (allow_digraphs) {
-
 
583
							return(1);
-
 
584
						}
-
 
585
					}
-
 
586
					p->tok = a;
-
 
587
				}
-
 
588
			}
-
 
589
			return(0);
-
 
590
 
-
 
591
		} else if (a == lex_dot && b == lex_integer_Hlit) {
-
 
592
			/* A dot may start a number */
-
 
593
			string s = q->pp_data.text;
-
 
594
			if (s[0] == char_dot) {
-
 
595
				return(0);
-
 
596
			}
-
 
597
			p->tok = lex_integer_Hlit;
-
 
598
			p->pp_data.text = xustrcat(token_name(a), s);
-
 
599
			return(1);
-
 
600
 
-
 
601
		} else if (a == lex_backslash && b == lex_identifier) {
-
 
602
			/* A backslash may start a universal character */
-
 
603
			/* NOT YET IMPLEMENTED */
-
 
604
			/* EMPTY */
-
 
605
		}
-
 
606
 
-
 
607
	} else if (a == lex_identifier) {
-
 
608
		HASHID nm = p->pp_data.id.hash;
-
 
609
		string s = DEREF_string(hashid_name_etc_text(nm));
-
 
610
		if (b == lex_identifier) {
-
 
611
			/* Two identifiers give another identifier */
-
 
612
			HASHID nm2 = q->pp_data.id.hash;
-
 
613
			string s2 = DEREF_string(hashid_name_etc_text(nm2));
-
 
614
			s = xustrcat(s, s2);
-
 
615
			nm = lookup_name(s, hash(s), 2, lex_identifier);
-
 
616
			p->pp_data.id.hash = nm;
-
 
617
			p->pp_data.id.use = DEREF_id(hashid_id(nm));
-
 
618
			return(1);
-
 
619
 
-
 
620
		} else if (b == lex_integer_Hlit) {
-
 
621
			/* An identifier and a number may give an identifier */
-
 
622
			character c;
-
 
623
			string n = q->pp_data.text;
-
 
624
			while (c = *(n++), c != 0) {
-
 
625
				if (c == char_dot || c == char_plus ||
-
 
626
				    c == char_minus) {
-
 
627
					/* The number must be entirely
-
 
628
					 * alphanumeric */
-
 
629
					return(0);
-
 
630
				}
-
 
631
			}
-
 
632
			s = xustrcat(s, q->pp_data.text);
-
 
633
			nm = lookup_name(s, hash(s), 2, lex_identifier);
-
 
634
			p->pp_data.id.hash = nm;
-
 
635
			p->pp_data.id.use = DEREF_id(hashid_id(nm));
-
 
636
			return(1);
-
 
637
 
-
 
638
		} else if (s[0] == char_L && s[1] == 0) {
-
 
639
			/* An L may start a wide character or string */
-
 
640
			if (b == lex_char_Hlit) {
-
 
641
				p->tok = lex_wchar_Hlit;
-
 
642
				p->pp_data.str.start = q->pp_data.str.start;
-
 
643
				p->pp_data.str.end = q->pp_data.str.end;
-
 
644
				return(1);
-
 
645
			} else if (b == lex_string_Hlit) {
-
 
646
				p->tok = lex_wstring_Hlit;
-
 
647
				p->pp_data.str.start = q->pp_data.str.start;
-
 
648
				p->pp_data.str.end = q->pp_data.str.end;
-
 
649
				return(1);
-
 
650
			}
-
 
651
		}
-
 
652
 
-
 
653
	} else if (a == lex_integer_Hlit) {
-
 
654
		string s = p->pp_data.text;
-
 
655
		if (b == lex_identifier) {
-
 
656
			/* A number followed by an identifier is a number */
-
 
657
			HASHID nm = q->pp_data.id.hash;
-
 
658
			string s2 = DEREF_string(hashid_name_etc_text(nm));
-
 
659
			p->pp_data.text = xustrcat(s, s2);
-
 
660
			return(1);
-
 
661
 
-
 
662
		} else if (b == lex_integer_Hlit) {
-
 
663
			/* Two numbers form another number */
-
 
664
			string s2 = q->pp_data.text;
-
 
665
			p->pp_data.text = xustrcat(s, s2);
-
 
666
			return(1);
-
 
667
 
-
 
668
		} else if (b == lex_dot || b == lex_ellipsis) {
-
 
669
			/* A number followed by a sequence of dots is a
-
 
670
			 * number */
-
 
671
			p->pp_data.text = xustrcat(s, token_name(b));
-
 
672
			return(1);
-
 
673
 
-
 
674
		} else if (b == lex_plus || b == lex_minus) {
-
 
675
			/* A sign may terminate a number after e or E */
-
 
676
			unsigned n = (unsigned)ustrlen(s) - 1;
-
 
677
			if (s[n] == char_e || s[n] == char_E) {
-
 
678
				p->pp_data.text = xustrcat(s, token_name(b));
-
 
679
				return(1);
-
 
680
			}
-
 
681
		}
-
 
682
	}
-
 
683
	return(0);
-
 
684
}
-
 
685
 
-
 
686
 
628
/*
687
/*
629
    DUMMY LOCATION FOR INPUT FILE
688
    DUMMY LOCATION FOR INPUT FILE
630
 
689
 
631
    This dummy location represents tokens read directly from the input file.
690
    This dummy location represents tokens read directly from the input file.
632
    If present, it will always be the last element of a list of token
691
    If present, it will always be the last element of a list of token
633
    locations.
692
    locations.
634
*/
693
*/
635
 
694
 
636
static PPTOKEN *dummy_loc_toks = NULL ;
695
static PPTOKEN *dummy_loc_toks = NULL;
637
static TOKEN_LOC dummy_loc = { &dummy_loc_toks, NULL } ;
696
static TOKEN_LOC dummy_loc = { &dummy_loc_toks, NULL };
638
TOKEN_LOC *file_loc = &dummy_loc ;
697
TOKEN_LOC *file_loc = &dummy_loc;
639
 
698
 
640
 
699
 
641
/*
700
/*
642
    FORWARD DECLARATION
701
    FORWARD DECLARATION
643
 
702
 
644
    The functions expand_macro, expand_toks and expand_tok_list are defined
703
    The functions expand_macro, expand_toks and expand_tok_list are defined
645
    recursively.  This gives the necessary forward declarations.
704
    recursively.  This gives the necessary forward declarations.
646
*/
705
*/
647
 
706
 
648
static PPTOKEN *expand_toks PROTO_S ( ( PPTOKEN *, TOKEN_LOC *, int ) ) ;
707
static PPTOKEN *expand_toks(PPTOKEN *, TOKEN_LOC *, int);
649
 
708
 
650
 
709
 
651
/*
710
/*
652
    HANDLE OLD STYLE STRINGISING
711
    HANDLE OLD STYLE STRINGISING
653
 
712
 
654
    This routine handles the old style stringising for the definition defn
713
    This routine handles the old style stringising for the definition defn
Line 662... Line 721...
662
    terminators.  This means that the X is recognised as a macro parameter
721
    terminators.  This means that the X is recognised as a macro parameter
663
    and is replaced during argument replacement.  The job of this routine
722
    and is replaced during argument replacement.  The job of this routine
664
    is to spot these unrecognised quotes and turn them into proper strings.
723
    is to spot these unrecognised quotes and turn them into proper strings.
665
*/
724
*/
666
 
725
 
667
PPTOKEN *recognise_strings
726
PPTOKEN *
668
    PROTO_N ( ( defn, macro, act ) )
-
 
669
    PROTO_T ( PPTOKEN *defn X HASHID macro X int act )
727
recognise_strings(PPTOKEN *defn, HASHID macro, int act)
670
{
728
{
671
    PPTOKEN *this_tok = defn ;
729
	PPTOKEN *this_tok = defn;
672
    PPTOKEN *last_tok = defn ;
730
	PPTOKEN *last_tok = defn;
673
    while ( this_tok != NULL ) {
731
	while (this_tok != NULL) {
674
	if ( this_tok->tok == lex_unknown ) {
732
		if (this_tok->tok == lex_unknown) {
675
	    unsigned long u ;
733
			unsigned long u;
676
	    int ch = CHAR_SIMPLE ;
734
			int ch = CHAR_SIMPLE;
677
	    character qo = char_question ;
735
			character qo = char_question;
678
	    u = get_multi_char ( this_tok->pp_data.buff, &ch ) ;
736
			u = get_multi_char(this_tok->pp_data.buff, &ch);
679
	    if ( ch == CHAR_SIMPLE ) qo = ( character ) u ;
737
			if (ch == CHAR_SIMPLE) {
-
 
738
				qo = (character)u;
-
 
739
			}
680
	    if ( qo == char_quote || qo == char_single_quote ) {
740
			if (qo == char_quote || qo == char_single_quote) {
681
		/* Start of string */
741
				/* Start of string */
682
		int t ;
742
				int t;
683
		int escaped = 0 ;
743
				int escaped = 0;
684
		PPTOKEN *next_tok = this_tok->next ;
744
				PPTOKEN *next_tok = this_tok->next;
685
		PPTOKEN *ptr_tok = next_tok ;
745
				PPTOKEN *ptr_tok = next_tok;
686
		while ( ptr_tok != NULL ) {
746
				while (ptr_tok != NULL) {
687
		    t = ptr_tok->tok ;
747
					t = ptr_tok->tok;
688
		    if ( t == lex_macro_Harg ) {
748
					if (t == lex_macro_Harg) {
-
 
749
						HASHID nm =
689
			HASHID nm = ptr_tok->pp_data.par.hash ;
750
						    ptr_tok->pp_data.par.hash;
-
 
751
						ERROR err =
690
			ERROR err = ERR_cpp_stringize_old ( nm, macro ) ;
752
						    ERR_cpp_stringize_old(nm,
-
 
753
									 macro);
691
			report ( preproc_loc, err ) ;
754
						report(preproc_loc, err);
692
		    }
755
					}
693
		    if ( escaped ) {
756
					if (escaped) {
694
			escaped = 0 ;
757
						escaped = 0;
695
		    } else if ( t == lex_unknown ) {
758
					} else if (t == lex_unknown) {
696
			character qc = char_question ;
759
						character qc = char_question;
697
			u = get_multi_char ( ptr_tok->pp_data.buff, &ch ) ;
760
						u = get_multi_char(ptr_tok->pp_data.buff, &ch);
698
			if ( ch == CHAR_SIMPLE ) qc = ( character ) u ;
761
						if (ch == CHAR_SIMPLE) {
-
 
762
							qc = (character)u;
-
 
763
						}
699
			if ( qc == qo ) break ;
764
						if (qc == qo) {
-
 
765
							break;
-
 
766
						}
700
			if ( qc == char_backslash ) escaped = 1 ;
767
						if (qc == char_backslash) {
-
 
768
							escaped = 1;
701
		    }
769
						}
-
 
770
					}
702
		    ptr_tok = ptr_tok->next ;
771
					ptr_tok = ptr_tok->next;
703
		}
772
				}
704
		if ( act ) {
773
				if (act) {
705
		    if ( ptr_tok == NULL ) {
774
					if (ptr_tok == NULL) {
706
			/* No closing quote */
775
						/* No closing quote */
-
 
776
						report(crt_loc,
707
			report ( crt_loc, ERR_cpp_stringize_bad ( macro ) ) ;
777
						  ERR_cpp_stringize_bad(macro));
708
			this_tok->next = NULL ;
778
						this_tok->next = NULL;
709
		    } else {
779
					} else {
710
			ptr_tok->tok = lex_ignore_token ;
780
						ptr_tok->tok = lex_ignore_token;
711
			this_tok->next = ptr_tok->next ;
781
						this_tok->next = ptr_tok->next;
712
			ptr_tok->next = NULL ;
782
						ptr_tok->next = NULL;
713
		    }
783
					}
714
 
784
 
715
		    /* Form the string */
785
					/* Form the string */
716
		    if ( !quote_tok_list ( next_tok, 0, ( int ) qo ) ) {
786
					if (!quote_tok_list(next_tok, 0,
-
 
787
							    (int)qo)) {
-
 
788
						report(crt_loc,
717
			report ( crt_loc, ERR_cpp_stringize_bad ( macro ) ) ;
789
						  ERR_cpp_stringize_bad(macro));
718
		    }
790
					}
-
 
791
					t = (qo == char_quote ?
719
		    t = ( qo == char_quote ? lex_string_Hlit : lex_char_Hlit ) ;
792
					     lex_string_Hlit : lex_char_Hlit);
720
		    this_tok->tok = t ;
793
					this_tok->tok = t;
721
		    token_parts ( t, this_tok ) ;
794
					token_parts(t, this_tok);
722
		    free_tok_list ( next_tok ) ;
795
					free_tok_list(next_tok);
723
 
796
 
724
		    /* Check for wide strings */
797
					/* Check for wide strings */
725
		    if ( last_tok->tok == lex_identifier ) {
798
					if (last_tok->tok == lex_identifier) {
726
			string s ;
799
						string s;
-
 
800
						HASHID nm =
727
			HASHID nm = last_tok->pp_data.id.hash ;
801
						    last_tok->pp_data.id.hash;
728
			s = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
802
						s = DEREF_string(hashid_name_etc_text(nm));
729
			if ( s [0] == char_L && s [1] == 0 ) {
803
						if (s[0] == char_L &&
-
 
804
						    s[1] == 0) {
-
 
805
							if (t ==
730
			    if ( t == lex_string_Hlit ) {
806
							    lex_string_Hlit) {
731
				t = lex_wstring_Hlit ;
807
								t = lex_wstring_Hlit;
732
			    } else {
808
							} else {
733
				t = lex_wchar_Hlit ;
809
								t = lex_wchar_Hlit;
734
			    }
810
							}
735
			    copy_pptok ( last_tok, t, this_tok ) ;
811
							copy_pptok(last_tok, t,
-
 
812
								   this_tok);
-
 
813
							last_tok->next =
736
			    last_tok->next = this_tok->next ;
814
							    this_tok->next;
737
			    free_pptok ( this_tok ) ;
815
							free_pptok(this_tok);
738
			    this_tok = last_tok ;
816
							this_tok = last_tok;
-
 
817
						}
-
 
818
					}
-
 
819
				}
739
			}
820
			}
740
		    }
-
 
741
		}
821
		}
742
	    }
822
		last_tok = this_tok;
-
 
823
		this_tok = this_tok->next;
743
	}
824
	}
744
	last_tok = this_tok ;
-
 
745
	this_tok = this_tok->next ;
-
 
746
    }
-
 
747
    return ( defn ) ;
825
	return(defn);
748
}
826
}
749
 
827
 
750
 
828
 
751
/*
829
/*
752
    HANDLE TOKEN CONCATENATION
830
    HANDLE TOKEN CONCATENATION
753
 
831
 
754
    This routine handles any ## operators in the definition defn of the
832
    This routine handles any ## operators in the definition defn of the
755
    given macro.  Note that any initial or terminal ## operators have
833
    given macro.  Note that any initial or terminal ## operators have
756
    already been reported.
834
    already been reported.
757
*/
835
*/
758
 
836
 
759
static PPTOKEN *process_concat
837
static PPTOKEN *
760
    PROTO_N ( ( defn, macro ) )
-
 
761
    PROTO_T ( PPTOKEN *defn X HASHID macro )
838
process_concat(PPTOKEN *defn, HASHID macro)
762
{
839
{
763
    PPTOKEN *this_tok ;
840
	PPTOKEN *this_tok;
764
    while ( defn && defn->tok == lex_hash_Hhash_Hop ) {
841
	while (defn && defn->tok == lex_hash_Hhash_Hop) {
765
	/* Check for initial ## */
842
		/* Check for initial ## */
766
	this_tok = defn ;
843
		this_tok = defn;
767
	defn = defn->next ;
844
		defn = defn->next;
768
	free_pptok ( this_tok ) ;
845
		free_pptok(this_tok);
769
    }
846
	}
770
    this_tok = defn ;
847
	this_tok = defn;
771
    while ( this_tok != NULL ) {
848
	while (this_tok != NULL) {
772
	PPTOKEN *next_tok = this_tok->next ;
849
		PPTOKEN *next_tok = this_tok->next;
773
	if ( next_tok == NULL ) break ;
850
		if (next_tok == NULL) {
-
 
851
			break;
-
 
852
		}
774
	if ( next_tok->tok == lex_hash_Hhash_Hop ) {
853
		if (next_tok->tok == lex_hash_Hhash_Hop) {
775
	    /* Delete the ## */
854
			/* Delete the ## */
776
	    this_tok->next = next_tok->next ;
855
			this_tok->next = next_tok->next;
777
	    free_pptok ( next_tok ) ;
856
			free_pptok(next_tok);
778
 
857
 
779
	    /* Check for terminal ## */
858
			/* Check for terminal ## */
780
	    if ( this_tok->next == NULL ) break ;
859
			if (this_tok->next == NULL) {
-
 
860
				break;
-
 
861
			}
781
 
862
 
782
	    /* Do the token concatenation */
863
			/* Do the token concatenation */
783
	    if ( concat_pptoks ( this_tok, this_tok->next ) ) {
864
			if (concat_pptoks(this_tok, this_tok->next)) {
784
		/* Delete the second argument if successful */
865
				/* Delete the second argument if successful */
785
		next_tok = this_tok->next ;
866
				next_tok = this_tok->next;
786
		this_tok->next = next_tok->next ;
867
				this_tok->next = next_tok->next;
787
		free_pptok ( next_tok ) ;
868
				free_pptok(next_tok);
788
	    } else {
869
			} else {
789
		report ( crt_loc, ERR_cpp_concat_bad ( macro ) ) ;
870
				report(crt_loc, ERR_cpp_concat_bad(macro));
790
	    }
871
			}
791
	    /* Now reprocess this_tok */
872
			/* Now reprocess this_tok */
792
	} else {
873
		} else {
793
	    this_tok = next_tok ;
874
			this_tok = next_tok;
794
	}
875
		}
795
    }
876
	}
796
    return ( defn ) ;
877
	return(defn);
797
}
878
}
798
 
879
 
799
 
880
 
800
/*
881
/*
801
    MAXIMUM NUMBER OF MACRO PARAMETERS
882
    MAXIMUM NUMBER OF MACRO PARAMETERS
802
 
883
 
803
    This macro defines the maximum number of macro parameters which
884
    This macro defines the maximum number of macro parameters which
Line 844... Line 925...
844
		    #define f( a )	a * g
925
		    #define f( a )	a * g
845
		    #define g( a )	f ( a )
926
		    #define g( a )	f ( a )
846
		    f ( 2 ) ( 9 )
927
		    f ( 2 ) ( 9 )
847
 
928
 
848
    the result is '2 * f ( 9 )', rather than '2 * 9 * g'.
929
    the result is '2 * f ( 9 )', rather than '2 * 9 * g'.
959
		}
1338
		}
960
		if ( ptr_tok != NULL ) {
1339
		if (arg_array != arg_array_base) {
961
		    /* Return the next token */
-
 
962
		    t = ptr_tok->tok ;
1340
			xfree_nof(arg_array);
963
		    ptr_tok = ptr_tok->next ;
-
 
964
		    break ;
-
 
965
		}
1341
		}
966
		/* Move on to next location */
-
 
967
		ptr_loc = ptr_loc->next ;
-
 
968
	    }
-
 
969
	}
-
 
970
 
-
 
971
	/* Next token is not an open bracket */
-
 
972
	if ( t != lex_open_Hround ) {
-
 
973
	    if ( complete ) {
-
 
974
		report ( loc, ERR_cpp_replace_arg_none ( macro ) ) ;
-
 
975
	    }
-
 
976
	    incomplete_macro : {
-
 
977
		/* Return macro identifier */
-
 
978
		this_tok = new_pptok () ;
-
 
979
		this_tok->tok = lex_identifier ;
-
 
980
		this_tok->next = NULL ;
-
 
981
		this_tok->pp_space = 0 ;
-
 
982
		this_tok->pp_data.id.hash = macro ;
-
 
983
		this_tok->pp_data.id.use = id ;
-
 
984
		return ( this_tok ) ;
-
 
985
	    }
-
 
986
	}
-
 
987
 
-
 
988
	/* Check argument array size */
-
 
989
	no_pars = DEREF_unsigned ( id_func_macro_no_params ( id ) ) ;
-
 
990
	if ( no_pars > MAX_MACRO_PARAMS ) {
-
 
991
	    arg_array = xmalloc_nof ( PPTOKEN *, no_pars + 1 ) ;
-
 
992
	}
-
 
993
 
-
 
994
	/* Scan macro arguments */
-
 
995
	for ( ; ; ) {
-
 
996
	    /* Get the next token */
-
 
997
	    int refill = 0 ;
-
 
998
	    for ( ; ; ) {
-
 
999
		if ( ptr_loc == file_loc ) {
-
 
1000
		    /* Read token from file location */
-
 
1001
		    sp = skip_white ( 1 ) ;
-
 
1002
		    in_preproc_dir = 2 ;
-
 
1003
		    t = read_token () ;
-
 
1004
		    update_column () ;
-
 
1005
		    if ( t == lex_hash_H1 || t == lex_hash_H2 ) {
-
 
1006
			if ( sp & WHITE_NEWLINE ) {
-
 
1007
			    /* Looks like preprocessing directive */
-
 
1008
			    ERROR err = ERR_cpp_replace_arg_ppdir ( macro ) ;
-
 
1009
			    report ( crt_loc, err ) ;
-
 
1010
			}
-
 
1011
		    }
-
 
1012
		    break ;
-
 
1013
		} else if ( ptr_loc == NULL ) {
-
 
1014
		    /* No more locations to read token from */
-
 
1015
		    t = lex_eof ;
-
 
1016
		    break ;
-
 
1017
		} else {
-
 
1018
		    /* Read token from next location */
-
 
1019
		    if ( refill ) ptr_tok = ( *( ptr_loc->toks ) )->next ;
-
 
1020
		    if ( ptr_tok != NULL ) {
-
 
1021
			t = ptr_tok->tok ;
-
 
1022
			break ;
-
 
1023
		    }
-
 
1024
		    ptr_loc = ptr_loc->next ;
-
 
1025
		    refill = 1 ;
-
 
1026
		}
-
 
1027
	    }
-
 
1028
 
-
 
1029
	    /* Examine this token */
-
 
1030
	    if ( t == lex_open_Hround ) {
-
 
1031
		brackets++ ;
-
 
1032
	    } else if ( t == lex_close_Hround ) {
-
 
1033
		/* Close brackets mark the end of the argument list */
-
 
1034
		if ( brackets == 0 ) break ;
-
 
1035
		brackets-- ;
-
 
1036
	    } else if ( t == lex_comma ) {
-
 
1037
		/* Commas mark the end of an argument */
-
 
1038
		if ( brackets == 0 ) {
-
 
1039
		    this_tok->next = NULL ;
-
 
1040
		    no_args++ ;
-
 
1041
		    if ( dummy_tok.next ) {
-
 
1042
			dummy_tok.next->pp_space = 0 ;
-
 
1043
		    } else if ( complete ) {
-
 
1044
			ERROR err ;
-
 
1045
			err = ERR_cpp_replace_arg_empty ( no_args, macro ) ;
-
 
1046
			report ( crt_loc, err ) ;
-
 
1047
		    }
-
 
1048
		    if ( no_args <= no_pars ) {
-
 
1049
			arg_array [ no_args ] = dummy_tok.next ;
-
 
1050
		    } else {
-
 
1051
			free_tok_list ( dummy_tok.next ) ;
-
 
1052
		    }
-
 
1053
		    if ( ptr_tok ) ptr_tok = ptr_tok->next ;
-
 
1054
		    this_tok = &dummy_tok ;
-
 
1055
		    continue ;
-
 
1056
		}
-
 
1057
	    } else if ( t == lex_eof ) {
-
 
1058
		break ;
-
 
1059
	    }
-
 
1060
 
-
 
1061
	    /* Build up current argument */
-
 
1062
	    this_tok->next = new_pptok () ;
-
 
1063
	    this_tok = this_tok->next ;
-
 
1064
	    if ( ptr_tok ) {
-
 
1065
		copy_pptok ( this_tok, t, ptr_tok ) ;
-
 
1066
		ptr_tok = ptr_tok->next ;
-
 
1067
	    } else {
-
 
1068
		this_tok->tok = t ;
-
 
1069
		if ( t <= LAST_COMPLEX_TOKEN ) token_parts ( t, this_tok ) ;
-
 
1070
		this_tok->pp_space = ( sp & WHITE_MASK ) ;
-
 
1071
	    }
-
 
1072
	}
-
 
1073
 
-
 
1074
	/* Create last argument */
-
 
1075
	in_preproc_dir = 0 ;
-
 
1076
	this_tok->next = NULL ;
-
 
1077
	if ( no_args || dummy_tok.next ) {
-
 
1078
	    no_args++ ;
-
 
1079
	    if ( dummy_tok.next ) {
-
 
1080
		dummy_tok.next->pp_space = 0 ;
-
 
1081
	    } else if ( complete ) {
-
 
1082
		ERROR err = ERR_cpp_replace_arg_empty ( no_args, macro ) ;
-
 
1083
		report ( crt_loc, err ) ;
-
 
1084
	    }
-
 
1085
	    if ( no_args <= no_pars ) {
-
 
1086
		arg_array [ no_args ] = dummy_tok.next ;
-
 
1087
	    } else {
-
 
1088
		free_tok_list ( dummy_tok.next ) ;
-
 
1089
	    }
-
 
1090
	}
-
 
1091
	if ( sp ) patch_white ( sp ) ;
-
 
1092
	this_tok = &dummy_tok ;
-
 
1093
 
-
 
1094
	/* Check for incomplete argument lists */
-
 
1095
	if ( t == lex_eof ) {
-
 
1096
	    if ( complete ) {
-
 
1097
		/* Report error, but carry on */
-
 
1098
		report ( loc, ERR_cpp_replace_arg_eof ( macro ) ) ;
-
 
1099
	    } else {
-
 
1100
		/* Free those arguments actually read */
-
 
1101
		for ( n = 1 ; n <= no_args && n <= no_pars ; n++ ) {
-
 
1102
		    free_tok_list ( arg_array [n] ) ;
-
 
1103
		}
-
 
1104
		if ( arg_array != arg_array_base ) xfree_nof ( arg_array ) ;
-
 
1105
		goto incomplete_macro ;
-
 
1106
	    }
-
 
1107
	}
1342
	}
1108
 
1343
 
1109
	/* Update location pointers */
-
 
1110
	if ( ptr_loc ) *( ptr_loc )->toks = ptr_tok ;
-
 
1111
	for ( lc = locs ; lc != ptr_loc ; lc = lc->next ) {
-
 
1112
	    *( lc )->toks = NULL ;
-
 
1113
	}
-
 
1114
 
-
 
1115
	/* Check that argument and parameter lists match */
-
 
1116
	if ( no_pars != no_args ) {
-
 
1117
	    ERROR err ;
-
 
1118
	    n = no_args ;
-
 
1119
	    err = ERR_cpp_replace_arg_number ( macro, n, n, no_pars ) ;
-
 
1120
	    report ( crt_loc, err ) ;
-
 
1121
 
-
 
1122
	    /* Add extra arguments if there are not enough */
-
 
1123
	    for ( n = no_args + 1 ; n <= no_pars ; n++ ) {
-
 
1124
		arg_array [n] = NULL ;
-
 
1125
	    }
-
 
1126
	}
-
 
1127
	IGNORE check_value ( OPT_VAL_macro_args, ( ulong ) no_args ) ;
-
 
1128
 
-
 
1129
	/* Get the macro definition */
-
 
1130
	defn = DEREF_pptok ( id_func_macro_defn ( id ) ) ;
-
 
1131
    }
-
 
1132
    crt_spaces = ws ;
-
 
1133
 
-
 
1134
    /* Copy the definition, expanding macro arguments */
-
 
1135
    while ( defn != NULL ) {
-
 
1136
	int t = defn->tok ;
-
 
1137
 
-
 
1138
	if ( t == lex_macro_Harg ) {
-
 
1139
	    /* Macro argument - identified by argument number */
-
 
1140
	    unsigned long n = defn->pp_data.par.no ;
-
 
1141
	    PPTOKEN *arg = arg_array [n] ;
-
 
1142
 
-
 
1143
	    if ( state == 0 ) {
-
 
1144
		if ( defn->next && defn->next->tok == lex_hash_Hhash_Hop ) {
-
 
1145
		    /* Preceding ##, just copy argument */
-
 
1146
		    this_tok->next = copy_tok_list ( arg ) ;
-
 
1147
		} else {
-
 
1148
		    /* Normal argument expansion */
-
 
1149
		    TOKEN_LOC *arg_locs = NULL ;
-
 
1150
		    this_tok->next = expand_toks ( arg, arg_locs, 0 ) ;
-
 
1151
		}
-
 
1152
 
-
 
1153
	    } else if ( state == 1 ) {
-
 
1154
		/* Following #, fake reading a string literal */
-
 
1155
		this_tok->next = new_pptok () ;
-
 
1156
		if ( !quote_tok_list ( arg, 1, char_quote ) ) {
-
 
1157
		    report ( crt_loc, ERR_cpp_stringize_bad ( macro ) ) ;
-
 
1158
		}
-
 
1159
		this_tok->next->tok = lex_string_Hlit ;
-
 
1160
		token_parts ( lex_string_Hlit, this_tok->next ) ;
-
 
1161
		this_tok->next->next = NULL ;
-
 
1162
		this_tok->next->pp_space = 0 ;
-
 
1163
 
-
 
1164
	    } else {
-
 
1165
		/* Following ##, just copy argument */
-
 
1166
		this_tok->next = copy_tok_list ( arg ) ;
-
 
1167
	    }
-
 
1168
 
-
 
1169
	    sp = defn->pp_space ;
-
 
1170
	    if ( sp && this_tok->next ) {
-
 
1171
		this_tok->next->pp_space = sp ;
-
 
1172
		sp = 0 ;
-
 
1173
	    }
-
 
1174
	    while ( this_tok->next ) this_tok = this_tok->next ;
-
 
1175
	    state = 0 ;
-
 
1176
 
-
 
1177
	} else if ( t == lex_hash_Hop ) {
-
 
1178
	    /* Check for # operator */
-
 
1179
	    state = 1 ;
-
 
1180
 
-
 
1181
	} else if ( t != lex_ignore_token ) {
-
 
1182
	    /* Copy other tokens */
-
 
1183
	    this_tok->next = new_pptok () ;
-
 
1184
	    this_tok = this_tok->next ;
-
 
1185
	    copy_pptok ( this_tok, t, defn ) ;
-
 
1186
	    if ( sp ) {
-
 
1187
		this_tok->pp_space = sp ;
-
 
1188
		sp = 0 ;
-
 
1189
	    }
-
 
1190
	    if ( t == lex_hash_Hhash_Hop ) {
-
 
1191
		/* Check for ## operator */
-
 
1192
		have_hash_hash = 1 ;
-
 
1193
		state = 2 ;
-
 
1194
	    } else {
-
 
1195
		if ( t == lex_unknown ) have_unknown = 1 ;
-
 
1196
		state = 0 ;
-
 
1197
	    }
-
 
1198
	}
-
 
1199
	defn = defn->next ;
-
 
1200
    }
-
 
1201
    this_tok->next = NULL ;
-
 
1202
    defn = dummy_tok.next ;
-
 
1203
 
-
 
1204
    /* Allow for argument expansion in strings */
-
 
1205
    if ( have_unknown ) defn = recognise_strings ( defn, macro, 1 ) ;
-
 
1206
 
-
 
1207
    /* Rescan for ## directives */
-
 
1208
    if ( have_hash_hash ) defn = process_concat ( defn, macro ) ;
-
 
1209
 
-
 
1210
    /* Rescan for further expansion (but not expanding macro) */
-
 
1211
    COPY_dspec ( id_storage ( id ), ( ds | dspec_temp ) ) ;
-
 
1212
    this_tok = expand_toks ( defn, locs, complete ) ;
-
 
1213
    free_tok_list ( defn ) ;
-
 
1214
    defn = this_tok ;
-
 
1215
    COPY_dspec ( id_storage ( id ), ds ) ;
-
 
1216
 
-
 
1217
    /* Clean up after macro expansion */
-
 
1218
    if ( tag == id_func_macro_tag ) {
-
 
1219
	/* Free the macro arguments */
-
 
1220
	unsigned n ;
-
 
1221
	for ( n = 1 ; n <= no_pars ; n++ ) free_tok_list ( arg_array [n] ) ;
-
 
1222
	if ( arg_array != arg_array_base ) xfree_nof ( arg_array ) ;
-
 
1223
    }
-
 
1224
 
-
 
1225
    /* Return the result */
1344
	/* Return the result */
1226
    return ( defn ) ;
1345
	return(defn);
1227
}
1346
}
1228
 
1347
 
1229
 
1348
 
1230
/*
1349
/*
1231
    EXPAND A LIST OF TOKENS
1350
    EXPAND A LIST OF TOKENS
1232
 
1351
 
1233
    This is the main macro expansion routine.  It expands the list of macros
1352
    This is the main macro expansion routine.  It expands the list of macros
1234
    tok, returning the result.  If toks ends in an unterminated function-like
1353
    tok, returning the result.  If toks ends in an unterminated function-like
1235
    macro then further tokens may be read from the locations given in locs.
1354
    macro then further tokens may be read from the locations given in locs.
1236
    The complete argument is as in expand_macro.
1355
    The complete argument is as in expand_macro.
1237
*/
1356
*/
1238
 
1357
 
1239
static PPTOKEN *expand_toks
1358
static PPTOKEN *
1240
    PROTO_N ( ( toks, locs, complete ) )
-
 
1241
    PROTO_T ( PPTOKEN *toks X TOKEN_LOC *locs X int complete )
1359
expand_toks(PPTOKEN *toks, TOKEN_LOC *locs, int complete)
1242
{
1360
{
1243
    PPTOKEN *ptr_tok ;
1361
	PPTOKEN *ptr_tok;
1244
    unsigned long sp = 0 ;
1362
	unsigned long sp = 0;
1245
    PPTOKEN dummy_tok, *this_tok = &dummy_tok ;
1363
	PPTOKEN dummy_tok, *this_tok = &dummy_tok;
1246
 
1364
 
1247
    /* Copy list of tokens */
1365
	/* Copy list of tokens */
1248
    for ( ptr_tok = toks ; ptr_tok != NULL ; ptr_tok = ptr_tok->next ) {
1366
	for (ptr_tok = toks; ptr_tok != NULL; ptr_tok = ptr_tok->next) {
1249
	int t = ptr_tok->tok ;
1367
		int t = ptr_tok->tok;
1250
	if ( t == lex_ignore_token ) {
1368
		if (t == lex_ignore_token) {
1251
	    sp |= ptr_tok->pp_space ;
1369
			sp |= ptr_tok->pp_space;
1252
	    continue ;
1370
			continue;
1253
	}
1371
		}
1254
	this_tok->next = new_pptok () ;
1372
		this_tok->next = new_pptok();
1255
	this_tok = this_tok->next ;
1373
		this_tok = this_tok->next;
1256
	copy_pptok ( this_tok, t, ptr_tok ) ;
1374
		copy_pptok(this_tok, t, ptr_tok);
1257
	if ( sp ) {
1375
		if (sp) {
1258
	    this_tok->pp_space |= sp ;
1376
			this_tok->pp_space |= sp;
1259
	    sp = 0 ;
1377
			sp = 0;
1260
	}
1378
		}
1261
 
1379
 
1262
	/* Check for macros */
1380
		/* Check for macros */
1263
	if ( t == lex_identifier ) {
1381
		if (t == lex_identifier) {
1264
	    HASHID m = ptr_tok->pp_data.id.hash ;
1382
			HASHID m = ptr_tok->pp_data.id.hash;
1265
	    IDENTIFIER id = DEREF_id ( hashid_id ( m ) ) ;
1383
			IDENTIFIER id = DEREF_id(hashid_id(m));
1266
	    unsigned tag = TAG_id ( id ) ;
1384
			unsigned tag = TAG_id(id);
1267
	    switch ( tag ) {
1385
			switch (tag) {
1268
		case id_obj_macro_tag :
1386
			case id_obj_macro_tag:
1269
		case id_func_macro_tag : {
1387
			case id_func_macro_tag: {
1270
		    DECL_SPEC ds ;
1388
				DECL_SPEC ds;
1271
		    TOKEN_LOC tloc ;
1389
				TOKEN_LOC tloc;
1272
 
1390
 
1273
		    /* Check for non-expanding tokens */
1391
				/* Check for non-expanding tokens */
1274
		    if ( IS_NULL_id ( this_tok->pp_data.id.use ) ) {
1392
				if (IS_NULL_id(this_tok->pp_data.id.use)) {
1275
			break ;
1393
					break;
1276
		    }
1394
				}
1277
 
1395
 
1278
		    /* Check for recursive macro definitions */
1396
				/* Check for recursive macro definitions */
1279
		    ds = DEREF_dspec ( id_storage ( id ) ) ;
1397
				ds = DEREF_dspec(id_storage(id));
1280
		    if ( ds & dspec_temp ) {
1398
				if (ds & dspec_temp) {
1281
			/* Mark this token as non-expanding */
1399
					/* Mark this token as non-expanding */
1282
			ERROR err = ERR_cpp_rescan_recursive ( m ) ;
1400
					ERROR err = ERR_cpp_rescan_recursive(m);
1283
			report ( crt_loc, err ) ;
1401
					report(crt_loc, err);
1284
			this_tok->pp_data.id.use = NULL_id ;
1402
					this_tok->pp_data.id.use = NULL_id;
1285
			break ;
1403
					break;
1286
		    }
1404
				}
1287
 
1405
 
1288
		    /* Expand the macro using an extra location */
1406
				/* Expand the macro using an extra location */
1289
		    tloc.toks = &ptr_tok ;
1407
				tloc.toks = &ptr_tok;
1290
		    tloc.next = locs ;
1408
				tloc.next = locs;
1291
		    this_tok->tok = lex_ignore_token ;
1409
				this_tok->tok = lex_ignore_token;
1292
		    this_tok->next = expand_macro ( m, &tloc, complete ) ;
1410
				this_tok->next = expand_macro(m, &tloc,
-
 
1411
							      complete);
1293
		    while ( this_tok->next ) this_tok = this_tok->next ;
1412
				while (this_tok->next)this_tok = this_tok->next;
1294
		    break ;
1413
				break;
1295
		}
1414
			}
1296
	    }
1415
			}
1297
	    if ( ptr_tok == NULL ) break ;
1416
			if (ptr_tok == NULL) {
-
 
1417
				break;
-
 
1418
			}
-
 
1419
		}
1298
	}
1420
	}
1299
    }
-
 
1300
    this_tok->next = NULL ;
1421
	this_tok->next = NULL;
1301
    return ( dummy_tok.next ) ;
1422
	return(dummy_tok.next);
1302
}
1423
}
1303
 
1424
 
1304
 
1425
 
1305
/*
1426
/*
1306
    EXPAND A SIMPLE LIST OF TOKENS
1427
    EXPAND A SIMPLE LIST OF TOKENS
1307
 
1428
 
1308
    This routine is the simplest form of expand_toks, where toks is a
1429
    This routine is the simplest form of expand_toks, where toks is a
1309
    complete list, with no locations for reading further tokens.
1430
    complete list, with no locations for reading further tokens.
1310
*/
1431
*/
1311
 
1432
 
1312
PPTOKEN *expand_tok_list
1433
PPTOKEN *
1313
    PROTO_N ( ( toks ) )
-
 
1314
    PROTO_T ( PPTOKEN *toks )
1434
expand_tok_list(PPTOKEN *toks)
1315
{
1435
{
1316
    return ( expand_toks ( toks, NIL ( TOKEN_LOC ), 1 ) ) ;
1436
	return(expand_toks(toks, NIL(TOKEN_LOC), 1));
1317
}
1437
}
1318
 
1438
 
1319
 
1439
 
1320
/*
1440
/*
1321
    ASSERTION NAMESPACE
1441
    ASSERTION NAMESPACE
1322
 
1442
 
1323
    The assertions occupy a namespace distinct from all other namespaces,
1443
    The assertions occupy a namespace distinct from all other namespaces,
1324
    including the macro namespace.
1444
    including the macro namespace.
1325
*/
1445
*/
1326
 
1446
 
1327
NAMESPACE assert_namespace ;
1447
NAMESPACE assert_namespace;
1328
 
1448
 
1329
 
1449
 
1330
/*
1450
/*
1331
    CREATE A BUILT-IN MACRO
1451
    CREATE A BUILT-IN MACRO
1332
 
1452
 
1333
    This routine creates a built-in macro named nm defined by a single
1453
    This routine creates a built-in macro named nm defined by a single
1334
    preprocessing token with token type t and associated data d.
1454
    preprocessing token with token type t and associated data d.
1335
*/
1455
*/
1336
 
1456
 
1337
static void builtin_macro
1457
static void
1338
    PROTO_N ( ( nm, t, d ) )
-
 
1339
    PROTO_T ( CONST char *nm X int t X CONST char *d )
1458
builtin_macro(CONST char *nm, int t, CONST char *d)
1340
{
1459
{
1341
    if ( d ) {
1460
	if (d) {
1342
	IDENTIFIER id ;
1461
		IDENTIFIER id;
1343
	string s = ustrlit ( nm ) ;
1462
		string s = ustrlit(nm);
1344
	unsigned long h = hash ( s ) ;
1463
		unsigned long h = hash(s);
1345
	HASHID macro = lookup_name ( s, h, 0, lex_identifier ) ;
1464
		HASHID macro = lookup_name(s, h, 0, lex_identifier);
1346
	IDENTIFIER pid = DEREF_id ( hashid_id ( macro ) ) ;
1465
		IDENTIFIER pid = DEREF_id(hashid_id(macro));
1347
	DECL_SPEC ds = ( dspec_defn | dspec_builtin ) ;
1466
		DECL_SPEC ds = (dspec_defn | dspec_builtin);
1348
 
1467
 
1349
	/* Set up the token definition */
1468
		/* Set up the token definition */
1350
	PPTOKEN *p = new_pptok () ;
1469
		PPTOKEN *p = new_pptok();
1351
	p->tok = t ;
1470
		p->tok = t;
1352
	p->pp_space = 0 ;
1471
		p->pp_space = 0;
1353
	p->pp_opts = NULL ;
1472
		p->pp_opts = NULL;
1354
	p->next = NULL ;
1473
		p->next = NULL;
1355
	if ( t == lex_integer_Hlit ) {
1474
		if (t == lex_integer_Hlit) {
1356
	    /* Set up associated integer data */
1475
			/* Set up associated integer data */
1357
	    string c = xustrcpy ( ustrlit ( d ) ) ;
1476
			string c = xustrcpy(ustrlit(d));
1358
	    p->pp_data.text = c ;
1477
			p->pp_data.text = c;
1359
	} else if ( t == lex_string_Hlit ) {
1478
		} else if (t == lex_string_Hlit) {
1360
	    /* Set up associated string data */
1479
			/* Set up associated string data */
1361
	    string c = xustrcpy ( ustrlit ( d ) ) ;
1480
			string c = xustrcpy(ustrlit(d));
1362
	    p->pp_data.str.start = c ;
1481
			p->pp_data.str.start = c;
1363
	    p->pp_data.str.end = c + ustrlen ( c ) ;
1482
			p->pp_data.str.end = c + ustrlen(c);
1364
	} else if ( t == lex_builtin_Hline || t == lex_builtin_Hfile ) {
1483
		} else if (t == lex_builtin_Hline || t == lex_builtin_Hfile) {
1365
	    /* Set up associated location data */
1484
			/* Set up associated location data */
1366
	    p->pp_space = crt_loc.column ;
1485
			p->pp_space = crt_loc.column;
1367
	    p->pp_data.loc.line = crt_loc.line ;
1486
			p->pp_data.loc.line = crt_loc.line;
1368
	    p->pp_data.loc.posn = crt_loc.posn ;
1487
			p->pp_data.loc.posn = crt_loc.posn;
1369
	}
1488
		}
1370
 
1489
 
1371
	/* Define the macro */
1490
		/* Define the macro */
1372
	MAKE_id_obj_macro ( macro, ds, NULL_nspace, crt_loc, p, id ) ;
1491
		MAKE_id_obj_macro(macro, ds, NULL_nspace, crt_loc, p, id);
1373
	COPY_id ( id_alias ( id ), pid ) ;
1492
		COPY_id(id_alias(id), pid);
1374
	COPY_id ( hashid_id ( macro ), id ) ;
1493
		COPY_id(hashid_id(macro), id);
-
 
1494
		if (do_macro) {
1375
	if ( do_macro ) dump_declare ( id, &crt_loc, 1 ) ;
1495
			dump_declare(id, &crt_loc, 1);
1376
    }
1496
		}
-
 
1497
	}
1377
    return ;
1498
	return;
1378
}
1499
}
1379
 
1500
 
1380
 
1501
 
1381
/*
1502
/*
1382
    INITIALISE BUILT-IN MACROS
1503
    INITIALISE BUILT-IN MACROS
1383
 
1504
 
1384
    This routine initialises the built-in macros, and sets up the assertion
1505
    This routine initialises the built-in macros, and sets up the assertion
1385
    namespace.
1506
    namespace.
1386
*/
1507
*/
1387
 
1508
 
1388
void init_macros
1509
void
1389
    PROTO_N ( ( m, a ) )
-
 
1390
    PROTO_T ( int m X int a )
1510
init_macros(int m, int a)
1391
{
1511
{
1392
    CONST char *d = find_date ( "%s %2d %d" ) ;
1512
	CONST char *d = find_date("%s %2d %d");
1393
    CONST char *t = find_time ( "%.2d:%.2d:%.2d" ) ;
1513
	CONST char *t = find_time("%.2d:%.2d:%.2d");
1394
    if ( m ) {
1514
	if (m) {
1395
	/* Define built-in macros */
1515
		/* Define built-in macros */
1396
	builtin_macro ( "__LINE__", lex_builtin_Hline, "1" ) ;
1516
		builtin_macro("__LINE__", lex_builtin_Hline, "1");
1397
	builtin_macro ( "__FILE__", lex_builtin_Hfile, "<unknown>" ) ;
1517
		builtin_macro("__FILE__", lex_builtin_Hfile, "<unknown>");
1398
	builtin_macro ( "__DATE__", lex_string_Hlit, d ) ;
1518
		builtin_macro("__DATE__", lex_string_Hlit, d);
1399
	builtin_macro ( "__TIME__", lex_string_Hlit, t ) ;
1519
		builtin_macro("__TIME__", lex_string_Hlit, t);
1400
	builtin_macro ( "__STDC__", lex_integer_Hlit, C_VERSION ) ;
1520
		builtin_macro("__STDC__", lex_integer_Hlit, C_VERSION);
1401
	builtin_macro ( "__STDC_VERSION__", lex_integer_Hlit, ISOC_VERSION ) ;
1521
		builtin_macro("__STDC_VERSION__", lex_integer_Hlit,
-
 
1522
			      ISOC_VERSION);
1402
#if LANGUAGE_CPP
1523
#if LANGUAGE_CPP
1403
	builtin_macro ( "__cplusplus", lex_integer_Hlit, CPP_VERSION ) ;
1524
		builtin_macro("__cplusplus", lex_integer_Hlit, CPP_VERSION);
1404
	builtin_macro ( "__tcpplus", lex_integer_Hlit, "1" ) ;
1525
		builtin_macro("__tcpplus", lex_integer_Hlit, "1");
1405
#else
1526
#else
1406
	builtin_macro ( "__tcpplus", lex_integer_Hlit, "0" ) ;
1527
		builtin_macro("__tcpplus", lex_integer_Hlit, "0");
1407
#endif
1528
#endif
1408
    }
1529
	}
1409
    assert_namespace = make_global_nspace ( "<assert>", 20 ) ;
1530
	assert_namespace = make_global_nspace("<assert>", 20);
1410
    if ( a ) {
1531
	if (a) {
1411
	/* Define built-in assertions */
1532
		/* Define built-in assertions */
1412
	IGNORE make_assert ( KEYWORD ( lex_include ), lex_include ) ;
1533
		IGNORE make_assert(KEYWORD(lex_include), lex_include);
1413
	IGNORE make_assert ( KEYWORD ( lex_keyword ), lex_keyword ) ;
1534
		IGNORE make_assert(KEYWORD(lex_keyword), lex_keyword);
1414
	IGNORE make_assert ( KEYWORD ( lex_option ), lex_option ) ;
1535
		IGNORE make_assert(KEYWORD(lex_option), lex_option);
1415
    }
1536
	}
1416
    return ;
1537
	return;
1417
}
1538
}