Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
6 7u83 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
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
6 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
6 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
6 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
6 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
6 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "system.h"
63
#include "version.h"
64
#include "c_types.h"
65
#include "hashid_ops.h"
66
#include "id_ops.h"
67
#include "nspace_ops.h"
68
#include "error.h"
69
#include "catalog.h"
70
#include "option.h"
71
#include "buffer.h"
72
#include "char.h"
73
#include "dump.h"
74
#include "file.h"
75
#include "hash.h"
76
#include "lex.h"
77
#include "literal.h"
78
#include "macro.h"
79
#include "namespace.h"
80
#include "predict.h"
81
#include "preproc.h"
82
#include "print.h"
83
#include "symbols.h"
84
#include "syntax.h"
85
#include "ustring.h"
86
#include "xalloc.h"
87
 
88
 
89
/*
90
    LIST OF FREE LEXICAL TOKENS
91
 
92
    All the free lexical tokens are formed into a list.
93
*/
94
 
6 7u83 95
PPTOKEN *free_tokens = NULL;
96
static LIST(PPTOKEN_P)alloc_tokens = NULL_list(PPTOKEN_P);
2 7u83 97
 
98
 
99
/*
100
    ALLOCATE A NEW TOKEN
101
 
102
    This routine allocates a new token from the list free_tokens.
103
*/
104
 
6 7u83 105
PPTOKEN *
106
new_pptok(void)
2 7u83 107
{
6 7u83 108
	PPTOKEN *p = free_tokens;
109
	if (p == NULL) {
110
		PPTOKEN *q;
111
		int i, n = 2000;
112
		p = xmalloc_nof(PPTOKEN, n);
113
		CONS_pptok(p, alloc_tokens, alloc_tokens);
114
		q = p;
115
		for (i = 1; i < n; i++) {
116
			q->next = q + 1;
117
			q++;
118
		}
119
		q->next = NULL;
2 7u83 120
	}
6 7u83 121
	free_tokens = p->next;
122
	p->pp_opts = real_opts;
123
	return(p);
2 7u83 124
}
125
 
126
 
127
/*
128
    FREE A SINGLE TOKEN
129
 
130
    This macro frees the single token P by adding it to the list of all
131
    free tokens.
132
*/
133
 
6 7u83 134
#define free_pptok(P)			\
135
    {					\
136
	(P)->next = free_tokens;	\
137
	free_tokens = (P);		\
2 7u83 138
    }
139
 
140
 
141
/*
142
    FREE A LIST OF TOKENS
143
 
144
    This routine adds the list of tokens p to the list of all free tokens.
145
*/
146
 
6 7u83 147
void
148
free_tok_list(PPTOKEN *p)
2 7u83 149
{
6 7u83 150
	PPTOKEN *q = p;
151
	if (q == NULL) {
152
		return;
153
	}
154
	while (q->next) {
155
		q = q->next;
156
	}
157
	q->next = free_tokens;
158
	free_tokens = p;
159
	return;
2 7u83 160
}
161
 
162
 
163
/*
164
    FREE ALL ALLOCATED PREPROCESSING TOKENS
165
 
166
    This routine frees all the space allocated for preprocessing tokens.
167
    It should only be called after the input has been completely processed.
168
*/
169
 
6 7u83 170
void
171
term_macros(void)
2 7u83 172
{
6 7u83 173
	LIST(PPTOKEN_P)p = alloc_tokens;
174
	while (!IS_NULL_list(p)) {
175
		PPTOKEN *q;
176
		DESTROY_CONS_pptok(destroy, q, p, p);
177
		xfree_nof(q);
178
	}
179
	alloc_tokens = p;
180
	free_tokens = NULL;
181
	return;
2 7u83 182
}
183
 
184
 
185
/*
186
    COPY A TOKEN
187
 
188
    This macro copies the contents of the token with token value T and data
189
    Q into P.
190
*/
191
 
6 7u83 192
#define copy_pptok(P, T, Q)		\
193
    {					\
194
	(P)->tok = (T);			\
195
	(P)->pp_data = (Q)->pp_data;	\
196
	(P)->pp_opts = (Q)->pp_opts;	\
197
	(P)->pp_space = (Q)->pp_space;	\
2 7u83 198
    }
199
 
200
 
201
/*
202
    ASSIGN TOKEN COMPONENTS
203
 
204
    This routine assigns the token components for the token t, which has
205
    just been read from the input file (or faked on occasions - these are
206
    indicated) into p.  It is only necessary to call this routine is T is
207
    less than or equal to LAST_COMPLEX_TOKEN (defined in symbols.h).  If any
208
    cases are added to this routine then it may be necessary to change the
209
    value of this macro.
210
*/
211
 
6 7u83 212
void
213
token_parts(int t, PPTOKEN *p)
2 7u83 214
{
6 7u83 215
	switch (t) {
216
	case lex_identifier: {
217
		/* Identifiers */
218
		HASHID nm = token_hashid;
219
		IDENTIFIER id = DEREF_id(hashid_id(nm));
220
		p->pp_data.id.hash = nm;
221
		p->pp_data.id.use = id;
222
		break;
2 7u83 223
	}
6 7u83 224
	case lex_char_Hlit:
225
	case lex_string_Hlit:
226
	case lex_wchar_Hlit:
227
	case lex_wstring_Hlit: {
228
		/* String and character literals */
229
		string s1 = token_buff.start;
230
		gen_size n = (gen_size)(token_buff.posn - s1);
231
		string s2;
232
		if (n < 2) {
233
			/* Optimise for small strings */
234
			s2 = xustrcpy(s1);
235
		} else {
236
			s2 = xustr(n + 1);
237
			xumemcpy(s2, s1, n);
238
			s2[n] = 0;
239
		}
240
		p->pp_data.str.start = s2;
241
		p->pp_data.str.end = s2 + n;
242
		break;
2 7u83 243
	}
6 7u83 244
	case lex_integer_Hlit:
245
		/* Integer and floating-point literals */
246
		p->pp_data.text = xustrcpy(token_buff.start);
247
		break;
248
	case lex_hash_Hif:
249
	case lex_hash_Helif:
250
		/* Target dependent conditionals */
251
		p->pp_data.exp = crt_hash_if_exp;
252
		break;
253
	case lex_unknown: {
254
		/* Unknown characters */
255
		int i;
256
		string s1 = token_buff.start;
257
		string s2 = p->pp_data.buff;
258
		ASSERT(MULTI_WIDTH <= sizeof(p->pp_data.buff));
259
		for (i = 0; i < MULTI_WIDTH; i++)s2[i] = s1[i];
260
		break;
2 7u83 261
	}
262
	}
6 7u83 263
	return;
2 7u83 264
}
265
 
266
 
267
/*
268
    REMOVE ANY IGNORED TOKENS FROM A LIST
269
 
270
    This routine removes any ignored tokens from the list tok, returning
271
    the result.
272
*/
273
 
6 7u83 274
PPTOKEN *
275
clean_tok_list(PPTOKEN *toks)
2 7u83 276
{
6 7u83 277
	unsigned long sp = 0;
278
	PPTOKEN p0, *p = &p0;
279
	PPTOKEN *q;
280
	p->next = toks;
281
	while (q = p->next, q != NULL) {
282
		if (q->tok == lex_ignore_token) {
283
			sp |= q->pp_space;
284
			p->next = q->next;
285
			free_pptok(q);
286
			q = p->next;
287
			if (q == NULL) {
288
				break;
289
			}
290
		} else {
291
			if (sp) {
292
				q->pp_space |= sp;
293
				sp = 0;
294
			}
295
		}
296
		p = q;
2 7u83 297
	}
6 7u83 298
	return(p0.next);
2 7u83 299
}
300
 
301
 
302
/*
303
    READ A LINE OF TOKENS
304
 
305
    This routine reads the sequence of preprocessing tokens comprising a
306
    preprocessing directive (for example, a macro definition).  If t1 is
307
    not lex_ignore_token then it is taken to be the first token in the
308
    definition, similarly tn gives the last token.
309
*/
310
 
6 7u83 311
PPTOKEN *
312
read_line(int t1, int tn)
2 7u83 313
{
6 7u83 314
	int t = t1;
315
	unsigned long sp = 0;
316
	PPTOKEN dummy_tok, *this_tok = &dummy_tok;
317
	if (t == lex_ignore_token) {
318
		t = read_token();
319
		update_column();
320
		if (in_preproc_dir) {
321
			preproc_loc = crt_loc;
322
		}
323
	}
324
	while (t != lex_newline && t != lex_eof) {
325
		this_tok->next = new_pptok();
326
		this_tok = this_tok->next;
327
		this_tok->tok = t;
328
		if (t <= LAST_COMPLEX_TOKEN) {
329
			token_parts(t, this_tok);
330
		}
331
		this_tok->pp_space = (sp & WHITE_MASK);
332
		sp = skip_white(0);
333
		t = read_token();
334
		update_column();
335
		if (in_preproc_dir) {
336
			preproc_loc = crt_loc;
337
		}
338
	}
339
	if (tn != lex_ignore_token) {
340
		this_tok->next = new_pptok();
341
		this_tok = this_tok->next;
342
		this_tok->tok = tn;
343
		token_parts(tn, this_tok);
344
		this_tok->pp_space = (sp & WHITE_MASK);
345
	}
346
	this_tok->next = NULL;
347
	if (in_preproc_dir) {
348
		IGNORE skip_to_end();
349
	}
350
	return(dummy_tok.next);
2 7u83 351
}
352
 
353
 
354
/*
355
    COPY A LIST OF TOKENS
356
 
357
    This routine copies the list of tokens toks, excluding any ignored
358
    tokens.
359
*/
360
 
6 7u83 361
static PPTOKEN *
362
copy_tok_list(PPTOKEN *toks)
2 7u83 363
{
6 7u83 364
	PPTOKEN *ptr_tok;
365
	PPTOKEN dummy_tok, *this_tok = &dummy_tok;
366
	for (ptr_tok = toks; ptr_tok != NULL; ptr_tok = ptr_tok->next) {
367
		int t = ptr_tok->tok;
368
		if (t != lex_ignore_token) {
369
			this_tok->next = new_pptok();
370
			this_tok = this_tok->next;
371
			copy_pptok(this_tok, t, ptr_tok);
372
		}
2 7u83 373
	}
6 7u83 374
	this_tok->next = NULL;
375
	return(dummy_tok.next);
2 7u83 376
}
377
 
378
 
379
/*
380
    STRINGISE A LIST OF TOKENS
381
 
382
    This routine turns the list of tokens toks into a string.  The result
383
    is built up in token_buff.  If esc is true then any '"' (or whatever
384
    the value of quote is) and '\' characters in string and character
385
    literals (including the initial and terminating quotes) are preceded
386
    by a '\'.  This routine is used in the implementation of the # operator,
387
    in macro #include directives and a couple of other preprocessing
388
    directives.  It returns 1 to indicate a valid string.
389
*/
390
 
6 7u83 391
int
392
quote_tok_list(PPTOKEN *toks, int esc, int quote)
2 7u83 393
{
6 7u83 394
	int res = 1;
395
	string st, se;
396
	int started = 0;
397
	int escaped = 0;
398
	PPTOKEN *ptr_tok;
399
	character qo = (character)quote;
400
	BUFFER *bf = clear_buffer(&token_buff, NIL(FILE));
2 7u83 401
 
6 7u83 402
	/* Scan through tokens */
403
	for (ptr_tok = toks; ptr_tok != NULL; ptr_tok = ptr_tok->next) {
404
		character p, q;
405
		int t = ptr_tok->tok;
406
		if (t == lex_ignore_token) {
407
			continue;
408
		}
2 7u83 409
 
6 7u83 410
		/* Print initial space if necessary */
411
		if (ptr_tok->pp_space && started) {
412
			bfputc(bf, char_space);
413
		}
2 7u83 414
 
6 7u83 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;
2 7u83 436
 
6 7u83 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);
2 7u83 445
 
6 7u83 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);
2 7u83 456
			}
457
 
6 7u83 458
			/* Closing quote */
459
			if (esc && q == qo) {
460
				bfputc(bf, char_backslash);
461
			}
462
			bfputc(bf, (int)q);
463
			break;
464
		case lex_wchar_Hlit:
465
			/* Wide character literals */
466
			p = char_L;
467
			q = char_single_quote;
468
			goto string_label;
469
		case lex_string_Hlit:
470
			/* String literals */
471
			p = 0;
472
			q = char_quote;
473
			goto string_label;
474
		case lex_wstring_Hlit:
475
			/* Wide string literals */
476
			p = char_L;
477
			q = char_quote;
478
			goto string_label;
479
		case lex_unknown: {
480
			/* Unknown characters */
481
			unsigned long u;
482
			int ch = CHAR_SIMPLE;
483
			u = get_multi_char(ptr_tok->pp_data.buff, &ch);
484
			if (ch == CHAR_SIMPLE) {
485
				bfputc(bf, (int)u);
486
			} else {
487
				print_char(u, ch, 0, bf);
488
			}
489
			break;
2 7u83 490
		}
6 7u83 491
		case lex_macro_Harg: {
492
			/* Macro parameters */
493
			HASHID nm = ptr_tok->pp_data.par.hash;
494
			st = DEREF_string(hashid_name_etc_text(nm));
495
			bfputs(bf, st);
496
			break;
2 7u83 497
		}
6 7u83 498
		default:
499
			/* Symbols */
500
			st = token_name(t);
501
			bfputs(bf, st);
502
			break;
503
		}
504
		started = 1;
2 7u83 505
	}
506
 
6 7u83 507
	/* End of string */
508
	bfputc(bf, 0);
509
	bf->posn--;
2 7u83 510
 
6 7u83 511
	/* Check for legal strings */
512
	st = bf->start;
513
	se = bf->posn;
514
	while (st != se) {
515
		if (escaped) {
516
			escaped = 0;
517
		} else {
518
			character c = *st;
519
			if (c == qo) {
520
				res = 0;
521
			}
522
			if (c == char_backslash) {
523
				escaped = 1;
524
			}
525
		}
526
		st++;
2 7u83 527
	}
6 7u83 528
	if (escaped) {
529
		res = 0;
530
	}
531
	return(res);
2 7u83 532
}
533
 
534
 
535
/*
536
    CONCATENATE TWO TOKENS
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
 
6 7u83 544
static int
545
concat_pptoks(PPTOKEN *p, PPTOKEN *q)
2 7u83 546
{
6 7u83 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
					}
2 7u83 568
#if LANGUAGE_CPP
6 7u83 569
					if (c >= FIRST_CPP_SYMBOL &&
570
					    c <= LAST_CPP_SYMBOL) {
571
						return(1);
572
					}
2 7u83 573
#endif
6 7u83 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 */
2 7u83 605
		}
606
 
6 7u83 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);
2 7u83 619
 
6 7u83 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);
2 7u83 637
 
6 7u83 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
			}
2 7u83 651
		}
652
 
6 7u83 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);
2 7u83 661
 
6 7u83 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);
2 7u83 667
 
6 7u83 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);
2 7u83 673
 
6 7u83 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
		}
2 7u83 682
	}
6 7u83 683
	return(0);
2 7u83 684
}
685
 
686
 
687
/*
688
    DUMMY LOCATION FOR INPUT FILE
689
 
690
    This dummy location represents tokens read directly from the input file.
691
    If present, it will always be the last element of a list of token
692
    locations.
693
*/
694
 
6 7u83 695
static PPTOKEN *dummy_loc_toks = NULL;
696
static TOKEN_LOC dummy_loc = { &dummy_loc_toks, NULL };
697
TOKEN_LOC *file_loc = &dummy_loc;
2 7u83 698
 
699
 
700
/*
701
    FORWARD DECLARATION
702
 
703
    The functions expand_macro, expand_toks and expand_tok_list are defined
704
    recursively.  This gives the necessary forward declarations.
705
*/
706
 
6 7u83 707
static PPTOKEN *expand_toks(PPTOKEN *, TOKEN_LOC *, int);
2 7u83 708
 
709
 
710
/*
711
    HANDLE OLD STYLE STRINGISING
712
 
713
    This routine handles the old style stringising for the definition defn
714
    for the given macro.  Argument replacement has already been performed
715
    on defn.  If this facility is enabled then in macro definitions of the
716
    form:
717
 
718
		#define f( X )	"X"
719
 
720
    quotes are classified as unknown characters rather than string
721
    terminators.  This means that the X is recognised as a macro parameter
722
    and is replaced during argument replacement.  The job of this routine
723
    is to spot these unrecognised quotes and turn them into proper strings.
724
*/
725
 
6 7u83 726
PPTOKEN *
727
recognise_strings(PPTOKEN *defn, HASHID macro, int act)
2 7u83 728
{
6 7u83 729
	PPTOKEN *this_tok = defn;
730
	PPTOKEN *last_tok = defn;
731
	while (this_tok != NULL) {
732
		if (this_tok->tok == lex_unknown) {
733
			unsigned long u;
734
			int ch = CHAR_SIMPLE;
735
			character qo = char_question;
736
			u = get_multi_char(this_tok->pp_data.buff, &ch);
737
			if (ch == CHAR_SIMPLE) {
738
				qo = (character)u;
739
			}
740
			if (qo == char_quote || qo == char_single_quote) {
741
				/* Start of string */
742
				int t;
743
				int escaped = 0;
744
				PPTOKEN *next_tok = this_tok->next;
745
				PPTOKEN *ptr_tok = next_tok;
746
				while (ptr_tok != NULL) {
747
					t = ptr_tok->tok;
748
					if (t == lex_macro_Harg) {
749
						HASHID nm =
750
						    ptr_tok->pp_data.par.hash;
751
						ERROR err =
752
						    ERR_cpp_stringize_old(nm,
753
									 macro);
754
						report(preproc_loc, err);
755
					}
756
					if (escaped) {
757
						escaped = 0;
758
					} else if (t == lex_unknown) {
759
						character qc = char_question;
760
						u = get_multi_char(ptr_tok->pp_data.buff, &ch);
761
						if (ch == CHAR_SIMPLE) {
762
							qc = (character)u;
763
						}
764
						if (qc == qo) {
765
							break;
766
						}
767
						if (qc == char_backslash) {
768
							escaped = 1;
769
						}
770
					}
771
					ptr_tok = ptr_tok->next;
772
				}
773
				if (act) {
774
					if (ptr_tok == NULL) {
775
						/* No closing quote */
776
						report(crt_loc,
777
						  ERR_cpp_stringize_bad(macro));
778
						this_tok->next = NULL;
779
					} else {
780
						ptr_tok->tok = lex_ignore_token;
781
						this_tok->next = ptr_tok->next;
782
						ptr_tok->next = NULL;
783
					}
2 7u83 784
 
6 7u83 785
					/* Form the string */
786
					if (!quote_tok_list(next_tok, 0,
787
							    (int)qo)) {
788
						report(crt_loc,
789
						  ERR_cpp_stringize_bad(macro));
790
					}
791
					t = (qo == char_quote ?
792
					     lex_string_Hlit : lex_char_Hlit);
793
					this_tok->tok = t;
794
					token_parts(t, this_tok);
795
					free_tok_list(next_tok);
2 7u83 796
 
6 7u83 797
					/* Check for wide strings */
798
					if (last_tok->tok == lex_identifier) {
799
						string s;
800
						HASHID nm =
801
						    last_tok->pp_data.id.hash;
802
						s = DEREF_string(hashid_name_etc_text(nm));
803
						if (s[0] == char_L &&
804
						    s[1] == 0) {
805
							if (t ==
806
							    lex_string_Hlit) {
807
								t = lex_wstring_Hlit;
808
							} else {
809
								t = lex_wchar_Hlit;
810
							}
811
							copy_pptok(last_tok, t,
812
								   this_tok);
813
							last_tok->next =
814
							    this_tok->next;
815
							free_pptok(this_tok);
816
							this_tok = last_tok;
817
						}
818
					}
819
				}
2 7u83 820
			}
821
		}
6 7u83 822
		last_tok = this_tok;
823
		this_tok = this_tok->next;
2 7u83 824
	}
6 7u83 825
	return(defn);
2 7u83 826
}
827
 
828
 
829
/*
830
    HANDLE TOKEN CONCATENATION
831
 
832
    This routine handles any ## operators in the definition defn of the
833
    given macro.  Note that any initial or terminal ## operators have
834
    already been reported.
835
*/
836
 
6 7u83 837
static PPTOKEN *
838
process_concat(PPTOKEN *defn, HASHID macro)
2 7u83 839
{
6 7u83 840
	PPTOKEN *this_tok;
841
	while (defn && defn->tok == lex_hash_Hhash_Hop) {
842
		/* Check for initial ## */
843
		this_tok = defn;
844
		defn = defn->next;
845
		free_pptok(this_tok);
846
	}
847
	this_tok = defn;
848
	while (this_tok != NULL) {
849
		PPTOKEN *next_tok = this_tok->next;
850
		if (next_tok == NULL) {
851
			break;
852
		}
853
		if (next_tok->tok == lex_hash_Hhash_Hop) {
854
			/* Delete the ## */
855
			this_tok->next = next_tok->next;
856
			free_pptok(next_tok);
2 7u83 857
 
6 7u83 858
			/* Check for terminal ## */
859
			if (this_tok->next == NULL) {
860
				break;
861
			}
2 7u83 862
 
6 7u83 863
			/* Do the token concatenation */
864
			if (concat_pptoks(this_tok, this_tok->next)) {
865
				/* Delete the second argument if successful */
866
				next_tok = this_tok->next;
867
				this_tok->next = next_tok->next;
868
				free_pptok(next_tok);
869
			} else {
870
				report(crt_loc, ERR_cpp_concat_bad(macro));
871
			}
872
			/* Now reprocess this_tok */
873
		} else {
874
			this_tok = next_tok;
875
		}
2 7u83 876
	}
6 7u83 877
	return(defn);
2 7u83 878
}
879
 
880
 
881
/*
882
    MAXIMUM NUMBER OF MACRO PARAMETERS
883
 
884
    This macro defines the maximum number of macro parameters which
885
    expand_macro can handle without having to allocate temporary space
886
    to hold them.  With allocation the number of parameters is unlimited.
887
*/
888
 
889
#define MAX_MACRO_PARAMS	256
890
 
891
 
892
/*
893
    EXPAND A MACRO DEFINITION
894
 
895
    This routine expands the macro given by the hash table entry macro.
896
    The argument locs gives a list of locations where macro arguments can
897
    be read from.  locs will never be NULL.  The argument complete is true
898
    to indicate that this is a complete macro expansion, and that any
899
    argument errors should be reported.  If locs contains file_loc then
900
    complete will always be true.  When reading from file_loc we always
901
    set in_preproc_dir to 2 to make read_token return lex_eof at the end
902
    of each file, rather than automatically reverting to the including
903
    file, and to cause it to ignore any preprocessing directives.
904
 
905
    Note that the entry for the macro in the hash table is marked during
906
    expansion to prevent recursive expansions.  Several points concerning
907
    macro expansion are undefined; in this implementation:
908
 
909
	1.  Firstly, # operators are evaluated from left to right;
910
	2.  Secondly, ## operators are evaluated from left to right;
911
	3.  If a ## b is not a valid preprocessing token then it is
912
	    resolved to a b;
913
	4.  A # operator in a function-like macro which is not followed
914
	    by a macro argument is ignored (it is left as # in object-like
915
	    macros of course);
916
	5.  A ## operator at the start or end of a macro is ignored;
917
	6.  Any preprocessing directives in the macro arguments are treated
918
	    as normal sequences of preprocessing tokens.
919
 
920
    A further undefined area concerns the ban on recursive macro expansions.
921
    This is extended from the macro definition itself to any extra tokens
922
    which are read during the expansion of the macro definition.  For
923
    example, in:
924
 
925
		    #define f( a )	a * g
926
		    #define g( a )	f ( a )
927
		    f ( 2 ) ( 9 )
928
 
929
    the result is '2 * f ( 9 )', rather than '2 * 9 * g'.
930
*/
931
 
6 7u83 932
PPTOKEN *
933
expand_macro(HASHID macro, TOKEN_LOC *locs, int complete)
2 7u83 934
{
6 7u83 935
	LOCATION loc;
936
	int state = 0;
937
	PPTOKEN *defn;
938
	unsigned long sp = 0;
939
	unsigned no_pars = 0;
940
	int have_unknown = 0;
941
	int have_hash_hash = 0;
942
	unsigned long ws = crt_spaces;
943
	PPTOKEN dummy_tok, *this_tok = &dummy_tok;
944
	PPTOKEN *arg_array_base[MAX_MACRO_PARAMS + 1];
945
	PPTOKEN **arg_array = arg_array_base;
2 7u83 946
 
6 7u83 947
	/* Get the macro identifier */
948
	IDENTIFIER id = DEREF_id(hashid_id(macro));
949
	unsigned tag = TAG_id(id);
950
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
2 7u83 951
 
6 7u83 952
	/* Mark the macro as being used */
953
	loc = crt_loc;
954
	ds |= dspec_used;
955
	COPY_dspec(id_storage(id), ds);
956
	if (do_macro && do_usage)dump_use(id, &crt_loc, 1);
2 7u83 957
 
6 7u83 958
	/* Get macro definition and other data */
959
	if (tag == id_obj_macro_tag) {
960
		/* Object-like macros */
961
		defn = DEREF_pptok(id_obj_macro_defn(id));
962
		if (defn == NULL) {
963
			return(NULL);
964
		}
2 7u83 965
 
6 7u83 966
		if (ds & dspec_builtin) {
967
			/* Check built-in macros */
968
			int t = defn->tok;
969
			if (t == lex_builtin_Hline) {
970
				/* Construct an integer literal for __LINE__ */
971
				BUFFER *bf = clear_buffer(&token_buff,
972
							  NIL(FILE));
973
				bfprintf(bf, "%lu", loc.line);
974
				bfputc(bf, 0);
975
				this_tok = new_pptok();
976
				this_tok->tok = lex_integer_Hlit;
977
				this_tok->next = NULL;
978
				this_tok->pp_opts = NULL;
979
				this_tok->pp_space = 0;
980
				token_parts(lex_integer_Hlit, this_tok);
981
				return(this_tok);
982
			}
2 7u83 983
 
6 7u83 984
			if (t == lex_builtin_Hfile) {
985
				/* Construct a string literal for __FILE__ */
986
				character c;
987
				string fn =
988
				    DEREF_string(posn_file(crt_loc.posn));
989
				BUFFER *bf = clear_buffer(&token_buff,
990
							  NIL(FILE));
991
				while (c = *(fn++), c != 0) {
992
					if (c == char_quote ||
993
					    c == char_backslash) {
994
						/* Escape quotes and
995
						 * backslashes */
996
						bfputc(bf, char_backslash);
997
					}
998
					bfputc(bf, (int)c);
999
				}
1000
				this_tok = new_pptok();
1001
				this_tok->tok = lex_string_Hlit;
1002
				this_tok->next = NULL;
1003
				this_tok->pp_opts = NULL;
1004
				this_tok->pp_space = 0;
1005
				token_parts(lex_string_Hlit, this_tok);
1006
				return(this_tok);
1007
			}
2 7u83 1008
		}
1009
 
6 7u83 1010
	} else {
1011
		/* Function-like macros */
1012
		int t;
1013
		unsigned n;
1014
		TOKEN_LOC *lc;
1015
		int brackets = 0;
1016
		unsigned no_args = 0;
1017
		PPTOKEN *ptr_tok = NULL;
1018
		TOKEN_LOC *ptr_loc = locs;
2 7u83 1019
 
6 7u83 1020
		/* Check for following open bracket */
1021
		for (;;) {
1022
			if (ptr_loc == file_loc) {
1023
				/* Read token from input location */
1024
				int legal = 1;
1025
				sp = skip_white(1);
1026
				if (peek_char(char_open_round, &legal)) {
1027
					/* Next token in file is '(' */
1028
					update_column();
1029
					t = lex_open_Hround;
1030
				} else {
1031
					/* Other cases */
1032
					t = lex_unknown;
1033
					if (sp)patch_white(sp);
1034
				}
1035
				break;
1036
			} else if (ptr_loc == NULL) {
1037
				/* No more locations */
1038
				t = lex_eof;
1039
				break;
1040
			} else {
1041
				/* Read token from current location */
1042
				ptr_tok = (*(ptr_loc->toks))->next;
1043
				while (ptr_tok && ptr_tok->tok ==
1044
				       lex_ignore_token) {
1045
					/* Step over any ignored tokens */
1046
					ptr_tok = ptr_tok->next;
1047
				}
1048
				if (ptr_tok != NULL) {
1049
					/* Return the next token */
1050
					t = ptr_tok->tok;
1051
					ptr_tok = ptr_tok->next;
1052
					break;
1053
				}
1054
				/* Move on to next location */
1055
				ptr_loc = ptr_loc->next;
1056
			}
2 7u83 1057
		}
6 7u83 1058
 
1059
		/* Next token is not an open bracket */
1060
		if (t != lex_open_Hround) {
1061
			if (complete) {
1062
				report(loc, ERR_cpp_replace_arg_none(macro));
1063
			}
1064
incomplete_macro:
1065
			/* Return macro identifier */
1066
			this_tok = new_pptok();
1067
			this_tok->tok = lex_identifier;
1068
			this_tok->next = NULL;
1069
			this_tok->pp_space = 0;
1070
			this_tok->pp_data.id.hash = macro;
1071
			this_tok->pp_data.id.use = id;
1072
			return(this_tok);
2 7u83 1073
		}
6 7u83 1074
 
1075
		/* Check argument array size */
1076
		no_pars = DEREF_unsigned(id_func_macro_no_params(id));
1077
		if (no_pars > MAX_MACRO_PARAMS) {
1078
			arg_array = xmalloc_nof(PPTOKEN *, no_pars + 1);
2 7u83 1079
		}
1080
 
6 7u83 1081
		/* Scan macro arguments */
1082
		for (;;) {
1083
			/* Get the next token */
1084
			int refill = 0;
1085
			for (;;) {
1086
				if (ptr_loc == file_loc) {
1087
					/* Read token from file location */
1088
					sp = skip_white(1);
1089
					in_preproc_dir = 2;
1090
					t = read_token();
1091
					update_column();
1092
					if (t == lex_hash_H1 ||
1093
					    t == lex_hash_H2) {
1094
						if (sp & WHITE_NEWLINE) {
1095
							/* Looks like
1096
							 * preprocessing
1097
							 * directive */
1098
							ERROR err = ERR_cpp_replace_arg_ppdir(macro);
1099
							report(crt_loc, err);
1100
						}
1101
					}
1102
					break;
1103
				} else if (ptr_loc == NULL) {
1104
					/* No more locations to read token
1105
					 * from */
1106
					t = lex_eof;
1107
					break;
1108
				} else {
1109
					/* Read token from next location */
1110
					if (refill)ptr_tok =
1111
						(*(ptr_loc->toks))->next;
1112
					if (ptr_tok != NULL) {
1113
						t = ptr_tok->tok;
1114
						break;
1115
					}
1116
					ptr_loc = ptr_loc->next;
1117
					refill = 1;
1118
				}
1119
			}
2 7u83 1120
 
6 7u83 1121
			/* Examine this token */
1122
			if (t == lex_open_Hround) {
1123
				brackets++;
1124
			} else if (t == lex_close_Hround) {
1125
				/* Close brackets mark the end of the argument
1126
				 * list */
1127
				if (brackets == 0) {
1128
					break;
1129
				}
1130
				brackets--;
1131
			} else if (t == lex_comma) {
1132
				/* Commas mark the end of an argument */
1133
				if (brackets == 0) {
1134
					this_tok->next = NULL;
1135
					no_args++;
1136
					if (dummy_tok.next) {
1137
						dummy_tok.next->pp_space = 0;
1138
					} else if (complete) {
1139
						ERROR err;
1140
						err = ERR_cpp_replace_arg_empty(no_args, macro);
1141
						report(crt_loc, err);
1142
					}
1143
					if (no_args <= no_pars) {
1144
						arg_array[no_args] = dummy_tok.next;
1145
					} else {
1146
						free_tok_list(dummy_tok.next);
1147
					}
1148
					if (ptr_tok) {
1149
						ptr_tok = ptr_tok->next;
1150
					}
1151
					this_tok = &dummy_tok;
1152
					continue;
1153
				}
1154
			} else if (t == lex_eof) {
1155
				break;
1156
			}
2 7u83 1157
 
6 7u83 1158
			/* Build up current argument */
1159
			this_tok->next = new_pptok();
1160
			this_tok = this_tok->next;
1161
			if (ptr_tok) {
1162
				copy_pptok(this_tok, t, ptr_tok);
1163
				ptr_tok = ptr_tok->next;
1164
			} else {
1165
				this_tok->tok = t;
1166
				if (t <= LAST_COMPLEX_TOKEN) {
1167
					token_parts(t, this_tok);
1168
				}
1169
				this_tok->pp_space = (sp & WHITE_MASK);
2 7u83 1170
			}
1171
		}
1172
 
6 7u83 1173
		/* Create last argument */
1174
		in_preproc_dir = 0;
1175
		this_tok->next = NULL;
1176
		if (no_args || dummy_tok.next) {
1177
			no_args++;
1178
			if (dummy_tok.next) {
1179
				dummy_tok.next->pp_space = 0;
1180
			} else if (complete) {
1181
				ERROR err = ERR_cpp_replace_arg_empty(no_args,
1182
								      macro);
1183
				report(crt_loc, err);
1184
			}
1185
			if (no_args <= no_pars) {
1186
				arg_array[no_args] = dummy_tok.next;
1187
			} else {
1188
				free_tok_list(dummy_tok.next);
1189
			}
2 7u83 1190
		}
6 7u83 1191
		if (sp)patch_white(sp);
1192
		this_tok = &dummy_tok;
2 7u83 1193
 
6 7u83 1194
		/* Check for incomplete argument lists */
1195
		if (t == lex_eof) {
1196
			if (complete) {
1197
				/* Report error, but carry on */
1198
				report(loc, ERR_cpp_replace_arg_eof(macro));
1199
			} else {
1200
				/* Free those arguments actually read */
1201
				for (n = 1; n <= no_args && n <= no_pars; n++) {
1202
					free_tok_list(arg_array[n]);
1203
				}
1204
				if (arg_array != arg_array_base) {
1205
					xfree_nof(arg_array);
1206
				}
1207
				goto incomplete_macro;
1208
			}
1209
		}
2 7u83 1210
 
6 7u83 1211
		/* Update location pointers */
1212
		if (ptr_loc) {
1213
			*(ptr_loc)->toks = ptr_tok;
2 7u83 1214
		}
6 7u83 1215
		for (lc = locs; lc != ptr_loc; lc = lc->next) {
1216
			*(lc)->toks = NULL;
1217
		}
2 7u83 1218
 
6 7u83 1219
		/* Check that argument and parameter lists match */
1220
		if (no_pars != no_args) {
1221
			ERROR err;
1222
			n = no_args;
1223
			err = ERR_cpp_replace_arg_number(macro, n, n, no_pars);
1224
			report(crt_loc, err);
2 7u83 1225
 
6 7u83 1226
			/* Add extra arguments if there are not enough */
1227
			for (n = no_args + 1; n <= no_pars; n++) {
1228
				arg_array[n] = NULL;
1229
			}
1230
		}
1231
		IGNORE check_value(OPT_VAL_macro_args, (ulong)no_args);
2 7u83 1232
 
6 7u83 1233
		/* Get the macro definition */
1234
		defn = DEREF_pptok(id_func_macro_defn(id));
2 7u83 1235
	}
6 7u83 1236
	crt_spaces = ws;
2 7u83 1237
 
6 7u83 1238
	/* Copy the definition, expanding macro arguments */
1239
	while (defn != NULL) {
1240
		int t = defn->tok;
2 7u83 1241
 
6 7u83 1242
		if (t == lex_macro_Harg) {
1243
			/* Macro argument - identified by argument number */
1244
			unsigned long n = defn->pp_data.par.no;
1245
			PPTOKEN *arg = arg_array[n];
2 7u83 1246
 
6 7u83 1247
			if (state == 0) {
1248
				if (defn->next &&
1249
				    defn->next->tok == lex_hash_Hhash_Hop) {
1250
					/* Preceding ##, just copy argument */
1251
					this_tok->next = copy_tok_list(arg);
1252
				} else {
1253
					/* Normal argument expansion */
1254
					TOKEN_LOC *arg_locs = NULL;
1255
					this_tok->next =
1256
					    expand_toks(arg, arg_locs, 0);
1257
				}
2 7u83 1258
 
6 7u83 1259
			} else if (state == 1) {
1260
				/* Following #, fake reading a string literal */
1261
				this_tok->next = new_pptok();
1262
				if (!quote_tok_list(arg, 1, char_quote)) {
1263
					report(crt_loc,
1264
					       ERR_cpp_stringize_bad(macro));
1265
				}
1266
				this_tok->next->tok = lex_string_Hlit;
1267
				token_parts(lex_string_Hlit, this_tok->next);
1268
				this_tok->next->next = NULL;
1269
				this_tok->next->pp_space = 0;
2 7u83 1270
 
6 7u83 1271
			} else {
1272
				/* Following ##, just copy argument */
1273
				this_tok->next = copy_tok_list(arg);
1274
			}
2 7u83 1275
 
6 7u83 1276
			sp = defn->pp_space;
1277
			if (sp && this_tok->next) {
1278
				this_tok->next->pp_space = sp;
1279
				sp = 0;
1280
			}
1281
			while (this_tok->next) {
1282
				this_tok = this_tok->next;
1283
			}
1284
			state = 0;
2 7u83 1285
 
6 7u83 1286
		} else if (t == lex_hash_Hop) {
1287
			/* Check for # operator */
1288
			state = 1;
2 7u83 1289
 
6 7u83 1290
		} else if (t != lex_ignore_token) {
1291
			/* Copy other tokens */
1292
			this_tok->next = new_pptok();
1293
			this_tok = this_tok->next;
1294
			copy_pptok(this_tok, t, defn);
1295
			if (sp) {
1296
				this_tok->pp_space = sp;
1297
				sp = 0;
1298
			}
1299
			if (t == lex_hash_Hhash_Hop) {
1300
				/* Check for ## operator */
1301
				have_hash_hash = 1;
1302
				state = 2;
1303
			} else {
1304
				if (t == lex_unknown) {
1305
					have_unknown = 1;
1306
				}
1307
				state = 0;
1308
			}
1309
		}
1310
		defn = defn->next;
1311
	}
1312
	this_tok->next = NULL;
1313
	defn = dummy_tok.next;
2 7u83 1314
 
6 7u83 1315
	/* Allow for argument expansion in strings */
1316
	if (have_unknown) {
1317
		defn = recognise_strings(defn, macro, 1);
2 7u83 1318
	}
1319
 
6 7u83 1320
	/* Rescan for ## directives */
1321
	if (have_hash_hash) {
1322
		defn = process_concat(defn, macro);
1323
	}
2 7u83 1324
 
6 7u83 1325
	/* Rescan for further expansion (but not expanding macro) */
1326
	COPY_dspec(id_storage(id), (ds | dspec_temp));
1327
	this_tok = expand_toks(defn, locs, complete);
1328
	free_tok_list(defn);
1329
	defn = this_tok;
1330
	COPY_dspec(id_storage(id), ds);
2 7u83 1331
 
6 7u83 1332
	/* Clean up after macro expansion */
1333
	if (tag == id_func_macro_tag) {
1334
		/* Free the macro arguments */
1335
		unsigned n;
1336
		for (n = 1; n <= no_pars; n++) {
1337
			free_tok_list(arg_array[n]);
1338
		}
1339
		if (arg_array != arg_array_base) {
1340
			xfree_nof(arg_array);
1341
		}
1342
	}
2 7u83 1343
 
6 7u83 1344
	/* Return the result */
1345
	return(defn);
2 7u83 1346
}
1347
 
1348
 
1349
/*
1350
    EXPAND A LIST OF TOKENS
1351
 
1352
    This is the main macro expansion routine.  It expands the list of macros
1353
    tok, returning the result.  If toks ends in an unterminated function-like
1354
    macro then further tokens may be read from the locations given in locs.
1355
    The complete argument is as in expand_macro.
1356
*/
1357
 
6 7u83 1358
static PPTOKEN *
1359
expand_toks(PPTOKEN *toks, TOKEN_LOC *locs, int complete)
2 7u83 1360
{
6 7u83 1361
	PPTOKEN *ptr_tok;
1362
	unsigned long sp = 0;
1363
	PPTOKEN dummy_tok, *this_tok = &dummy_tok;
2 7u83 1364
 
6 7u83 1365
	/* Copy list of tokens */
1366
	for (ptr_tok = toks; ptr_tok != NULL; ptr_tok = ptr_tok->next) {
1367
		int t = ptr_tok->tok;
1368
		if (t == lex_ignore_token) {
1369
			sp |= ptr_tok->pp_space;
1370
			continue;
1371
		}
1372
		this_tok->next = new_pptok();
1373
		this_tok = this_tok->next;
1374
		copy_pptok(this_tok, t, ptr_tok);
1375
		if (sp) {
1376
			this_tok->pp_space |= sp;
1377
			sp = 0;
1378
		}
2 7u83 1379
 
6 7u83 1380
		/* Check for macros */
1381
		if (t == lex_identifier) {
1382
			HASHID m = ptr_tok->pp_data.id.hash;
1383
			IDENTIFIER id = DEREF_id(hashid_id(m));
1384
			unsigned tag = TAG_id(id);
1385
			switch (tag) {
1386
			case id_obj_macro_tag:
1387
			case id_func_macro_tag: {
1388
				DECL_SPEC ds;
1389
				TOKEN_LOC tloc;
2 7u83 1390
 
6 7u83 1391
				/* Check for non-expanding tokens */
1392
				if (IS_NULL_id(this_tok->pp_data.id.use)) {
1393
					break;
1394
				}
2 7u83 1395
 
6 7u83 1396
				/* Check for recursive macro definitions */
1397
				ds = DEREF_dspec(id_storage(id));
1398
				if (ds & dspec_temp) {
1399
					/* Mark this token as non-expanding */
1400
					ERROR err = ERR_cpp_rescan_recursive(m);
1401
					report(crt_loc, err);
1402
					this_tok->pp_data.id.use = NULL_id;
1403
					break;
1404
				}
2 7u83 1405
 
6 7u83 1406
				/* Expand the macro using an extra location */
1407
				tloc.toks = &ptr_tok;
1408
				tloc.next = locs;
1409
				this_tok->tok = lex_ignore_token;
1410
				this_tok->next = expand_macro(m, &tloc,
1411
							      complete);
1412
				while (this_tok->next)this_tok = this_tok->next;
1413
				break;
1414
			}
1415
			}
1416
			if (ptr_tok == NULL) {
1417
				break;
1418
			}
2 7u83 1419
		}
1420
	}
6 7u83 1421
	this_tok->next = NULL;
1422
	return(dummy_tok.next);
2 7u83 1423
}
1424
 
1425
 
1426
/*
1427
    EXPAND A SIMPLE LIST OF TOKENS
1428
 
1429
    This routine is the simplest form of expand_toks, where toks is a
1430
    complete list, with no locations for reading further tokens.
1431
*/
1432
 
6 7u83 1433
PPTOKEN *
1434
expand_tok_list(PPTOKEN *toks)
2 7u83 1435
{
6 7u83 1436
	return(expand_toks(toks, NIL(TOKEN_LOC), 1));
2 7u83 1437
}
1438
 
1439
 
1440
/*
1441
    ASSERTION NAMESPACE
1442
 
1443
    The assertions occupy a namespace distinct from all other namespaces,
1444
    including the macro namespace.
1445
*/
1446
 
6 7u83 1447
NAMESPACE assert_namespace;
2 7u83 1448
 
1449
 
1450
/*
1451
    CREATE A BUILT-IN MACRO
1452
 
1453
    This routine creates a built-in macro named nm defined by a single
1454
    preprocessing token with token type t and associated data d.
1455
*/
1456
 
6 7u83 1457
static void
1458
builtin_macro(CONST char *nm, int t, CONST char *d)
2 7u83 1459
{
6 7u83 1460
	if (d) {
1461
		IDENTIFIER id;
1462
		string s = ustrlit(nm);
1463
		unsigned long h = hash(s);
1464
		HASHID macro = lookup_name(s, h, 0, lex_identifier);
1465
		IDENTIFIER pid = DEREF_id(hashid_id(macro));
1466
		DECL_SPEC ds = (dspec_defn | dspec_builtin);
2 7u83 1467
 
6 7u83 1468
		/* Set up the token definition */
1469
		PPTOKEN *p = new_pptok();
1470
		p->tok = t;
1471
		p->pp_space = 0;
1472
		p->pp_opts = NULL;
1473
		p->next = NULL;
1474
		if (t == lex_integer_Hlit) {
1475
			/* Set up associated integer data */
1476
			string c = xustrcpy(ustrlit(d));
1477
			p->pp_data.text = c;
1478
		} else if (t == lex_string_Hlit) {
1479
			/* Set up associated string data */
1480
			string c = xustrcpy(ustrlit(d));
1481
			p->pp_data.str.start = c;
1482
			p->pp_data.str.end = c + ustrlen(c);
1483
		} else if (t == lex_builtin_Hline || t == lex_builtin_Hfile) {
1484
			/* Set up associated location data */
1485
			p->pp_space = crt_loc.column;
1486
			p->pp_data.loc.line = crt_loc.line;
1487
			p->pp_data.loc.posn = crt_loc.posn;
1488
		}
1489
 
1490
		/* Define the macro */
1491
		MAKE_id_obj_macro(macro, ds, NULL_nspace, crt_loc, p, id);
1492
		COPY_id(id_alias(id), pid);
1493
		COPY_id(hashid_id(macro), id);
1494
		if (do_macro) {
1495
			dump_declare(id, &crt_loc, 1);
1496
		}
2 7u83 1497
	}
6 7u83 1498
	return;
2 7u83 1499
}
1500
 
1501
 
1502
/*
1503
    INITIALISE BUILT-IN MACROS
1504
 
1505
    This routine initialises the built-in macros, and sets up the assertion
1506
    namespace.
1507
*/
1508
 
6 7u83 1509
void
1510
init_macros(int m, int a)
2 7u83 1511
{
6 7u83 1512
	CONST char *d = find_date("%s %2d %d");
1513
	CONST char *t = find_time("%.2d:%.2d:%.2d");
1514
	if (m) {
1515
		/* Define built-in macros */
1516
		builtin_macro("__LINE__", lex_builtin_Hline, "1");
1517
		builtin_macro("__FILE__", lex_builtin_Hfile, "<unknown>");
1518
		builtin_macro("__DATE__", lex_string_Hlit, d);
1519
		builtin_macro("__TIME__", lex_string_Hlit, t);
1520
		builtin_macro("__STDC__", lex_integer_Hlit, C_VERSION);
1521
		builtin_macro("__STDC_VERSION__", lex_integer_Hlit,
1522
			      ISOC_VERSION);
2 7u83 1523
#if LANGUAGE_CPP
6 7u83 1524
		builtin_macro("__cplusplus", lex_integer_Hlit, CPP_VERSION);
1525
		builtin_macro("__tcpplus", lex_integer_Hlit, "1");
2 7u83 1526
#else
6 7u83 1527
		builtin_macro("__tcpplus", lex_integer_Hlit, "0");
2 7u83 1528
#endif
6 7u83 1529
	}
1530
	assert_namespace = make_global_nspace("<assert>", 20);
1531
	if (a) {
1532
		/* Define built-in assertions */
1533
		IGNORE make_assert(KEYWORD(lex_include), lex_include);
1534
		IGNORE make_assert(KEYWORD(lex_keyword), lex_keyword);
1535
		IGNORE make_assert(KEYWORD(lex_option), lex_option);
1536
	}
1537
	return;
2 7u83 1538
}