]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cpptrad.c
Individual processor configurations for sh-elf / sh-linux:
[thirdparty/gcc.git] / gcc / cpptrad.c
CommitLineData
004cb263
NB
1/* CPP Library - traditional lexical analysis and macro expansion.
2 Copyright (C) 2002 Free Software Foundation, Inc.
3 Contributed by Neil Booth, May 2002
4
5This program is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19#include "config.h"
20#include "system.h"
21#include "cpplib.h"
22#include "cpphash.h"
23
c70f6ed3
NB
24/* The replacement text of a function-like macro is stored as a
25 contiguous sequence of aligned blocks. Each block represents the
26 portion of text from the start of the previous block (or the start
27 of the macro replacement text in the case of the first block) to
28 the next parameter, or the end of the replacement list if there
29 are none left.
30
31 Each block consists of an unsigned int, which is the length of text
32 contained in the third part, an unsigned short, which is the
33 one-based index of the argument that immediately follows that text,
34 and the text itself. The final block in the macro expansion is
35 recognizable as it has an argument index of zero. */
36
37struct block
38{
39 unsigned int text_len;
40 unsigned short arg_index;
41 uchar text[1];
42};
43
44#define BLOCK_HEADER_LEN offsetof (struct block, text)
45#define BLOCK_LEN(TEXT_LEN) CPP_ALIGN (BLOCK_HEADER_LEN + TEXT_LEN)
46
1ce676a0
NB
47/* Structure holding information about a function-like macro
48 invocation. */
49struct fun_macro
50{
51 /* Memory buffer holding the trad_arg array. */
52 _cpp_buff *buff;
53
54 /* An array of size the number of macro parameters + 1, containing
55 the offsets of the start of each macro argument in the output
56 buffer. The argument continues until the character before the
57 start of the next one. */
58 size_t *args;
59
60 /* The hashnode of the macro. */
61 cpp_hashnode *node;
62
63 /* The offset of the macro name in the output buffer. */
64 size_t offset;
65
66 /* Zero-based index of argument being currently lexed. */
67 unsigned int argc;
68};
69
43612ffb
NB
70/* Lexing TODO: Handle -C, maybe -CC, and space in escaped newlines.
71 Stop cpplex.c from recognizing comments and directives during its
cbc69f84
NB
72 lexing pass. Get rid of line_base usage - seems pointless? Do we
73 get escaped newline at EOF correct? */
004cb263
NB
74
75static const uchar *handle_newline PARAMS ((cpp_reader *, const uchar *));
76static const uchar *skip_escaped_newlines PARAMS ((cpp_reader *,
77 const uchar *));
cbc69f84 78static const uchar *skip_whitespace PARAMS ((cpp_reader *, const uchar *));
004cb263
NB
79static cpp_hashnode *lex_identifier PARAMS ((cpp_reader *, const uchar *));
80static const uchar *skip_comment PARAMS ((cpp_reader *, const uchar *));
c70f6ed3 81static void scan_out_logical_line PARAMS ((cpp_reader *pfile, cpp_macro *));
004cb263 82static void check_output_buffer PARAMS ((cpp_reader *, size_t));
cbc69f84 83static void push_replacement_text PARAMS ((cpp_reader *, cpp_hashnode *));
c70f6ed3 84static bool scan_parameters PARAMS ((cpp_reader *, cpp_macro *));
974c43f1 85static bool recursive_macro PARAMS ((cpp_reader *, cpp_hashnode *));
c70f6ed3
NB
86static void save_replacement_text PARAMS ((cpp_reader *, cpp_macro *,
87 unsigned int));
1ce676a0
NB
88static void maybe_start_funlike PARAMS ((cpp_reader *, cpp_hashnode *,
89 const uchar *, struct fun_macro *));
90static void save_argument PARAMS ((struct fun_macro *, size_t));
91static void replace_args_and_push PARAMS ((cpp_reader *, struct fun_macro *));
6618c5d4
NB
92static size_t canonicalize_text PARAMS ((uchar *, const uchar *, size_t,
93 uchar *));
004cb263
NB
94
95/* Ensures we have N bytes' space in the output buffer, and
96 reallocates it if not. */
97static void
98check_output_buffer (pfile, n)
99 cpp_reader *pfile;
100 size_t n;
101{
1a76916c 102 if (n > (size_t) (pfile->out.limit - pfile->out.cur))
004cb263 103 {
1a76916c 104 size_t size = pfile->out.cur - pfile->out.base;
004cb263
NB
105 size_t new_size = (size + n) * 3 / 2;
106
1a76916c
NB
107 pfile->out.base
108 = (uchar *) xrealloc (pfile->out.base, new_size);
109 pfile->out.limit = pfile->out.base + new_size;
110 pfile->out.cur = pfile->out.base + size;
004cb263
NB
111 }
112}
113
114/* To be called whenever a newline character is encountered in the
115 input file, at CUR. Handles DOS, MAC and Unix ends of line, and
116 returns the character after the newline sequence. */
117static const uchar *
118handle_newline (pfile, cur)
119 cpp_reader *pfile;
120 const uchar *cur;
121{
122 pfile->line++;
123 if (cur[0] + cur[1] == '\r' + '\n')
124 cur++;
43612ffb 125 pfile->buffer->line_base = cur + 1;
004cb263
NB
126 return cur + 1;
127}
128
129/* CUR points to any character in the buffer, not necessarily a
130 backslash. Advances CUR until all escaped newlines are skipped,
131 and returns the new position. */
132static const uchar *
133skip_escaped_newlines (pfile, cur)
134 cpp_reader *pfile;
135 const uchar *cur;
136{
137 while (*cur == '\\' && is_vspace (cur[1]))
138 cur = handle_newline (pfile, cur + 1);
139
140 return cur;
141}
142
143/* CUR points to the character after the asterisk introducing a
144 comment. Returns the position after the comment. */
145static const uchar *
146skip_comment (pfile, cur)
147 cpp_reader *pfile;
148 const uchar *cur;
149{
150 unsigned int from_line = pfile->line;
82eda77e
NB
151 unsigned int c = 0, prevc = 0;
152 const uchar *limit = RLIMIT (pfile->context);
004cb263 153
43612ffb 154 while (cur < limit)
004cb263 155 {
43612ffb
NB
156 prevc = c;
157 c = *cur++;
158
159 if (c == '/')
004cb263 160 {
43612ffb
NB
161 if (prevc == '*')
162 break;
163 if (*cur == '*' && cur[1] != '/'
164 && CPP_OPTION (pfile, warn_comments))
165 cpp_error_with_line (pfile, DL_WARNING, pfile->line, 0,
166 "\"/*\" within comment");
004cb263
NB
167 }
168 else if (is_vspace (c))
169 cur = handle_newline (pfile, cur - 1);
004cb263
NB
170 }
171
43612ffb
NB
172 if (c != '/' || prevc != '*')
173 cpp_error_with_line (pfile, DL_ERROR, from_line, 0,
174 "unterminated comment");
175
004cb263
NB
176 return cur;
177}
178
cbc69f84
NB
179/* Skip any horizontal whitespace and comments beginning at CUR,
180 returning the following character. */
181static const uchar *
182skip_whitespace (pfile, cur)
183 cpp_reader *pfile;
184 const uchar *cur;
185{
186 const uchar *tmp;
187
188 for (;;)
189 {
190 while (is_nvspace (*cur) && *cur != 0)
191 cur++;
192
193 if (*cur == '\0' && cur != RLIMIT (pfile->context))
194 continue;
195
196 if (*cur == '\\')
197 {
198 tmp = cur;
199 cur = skip_escaped_newlines (pfile, cur);
200 if (tmp != cur)
201 continue;
202 }
203
204 if (*cur == '/')
205 {
206 tmp = skip_escaped_newlines (pfile, cur + 1);
207 if (*tmp == '*')
208 {
209 cur = skip_comment (pfile, tmp + 1);
210 continue;
211 }
212 }
213
214 break;
215 }
216
217 return cur;
218}
219
004cb263
NB
220/* Lexes and outputs an identifier starting at CUR, which is assumed
221 to point to a valid first character of an identifier. Returns
1a76916c 222 the hashnode, and updates out.cur. */
004cb263
NB
223static cpp_hashnode *
224lex_identifier (pfile, cur)
225 cpp_reader *pfile;
226 const uchar *cur;
227{
228 size_t len;
1a76916c 229 uchar *out = pfile->out.cur;
cbc69f84 230 cpp_hashnode *result;
004cb263
NB
231
232 do
233 {
234 do
235 *out++ = *cur++;
1ce676a0 236 while (is_numchar (*cur));
004cb263
NB
237 cur = skip_escaped_newlines (pfile, cur);
238 }
1ce676a0 239 while (is_numchar (*cur));
004cb263 240
82eda77e 241 CUR (pfile->context) = cur;
1a76916c
NB
242 len = out - pfile->out.cur;
243 result = (cpp_hashnode *) ht_lookup (pfile->hash_table, pfile->out.cur,
cbc69f84 244 len, HT_ALLOC);
1a76916c 245 pfile->out.cur = out;
cbc69f84
NB
246 return result;
247}
248
249/* Reads an identifier, returning its hashnode. If the next token is
250 not an identifier, returns NULL. */
251cpp_hashnode *
252_cpp_lex_identifier_trad (pfile)
253 cpp_reader *pfile;
254{
255 const uchar *cur = skip_whitespace (pfile, CUR (pfile->context));
256
1ce676a0 257 if (!is_idstart (*cur))
cbc69f84
NB
258 {
259 CUR (pfile->context) = cur;
260 return NULL;
261 }
262
263 return lex_identifier (pfile, cur);
004cb263
NB
264}
265
266/* Overlays the true file buffer temporarily with text of length LEN
267 starting at START. The true buffer is restored upon calling
268 restore_buff(). */
269void
270_cpp_overlay_buffer (pfile, start, len)
271 cpp_reader *pfile;
272 const uchar *start;
273 size_t len;
274{
275 cpp_buffer *buffer = pfile->buffer;
276
277 buffer->saved_cur = buffer->cur;
278 buffer->saved_rlimit = buffer->rlimit;
279 buffer->saved_line_base = buffer->line_base;
280
281 buffer->cur = start;
282 buffer->line_base = start;
283 buffer->rlimit = start + len;
1a76916c
NB
284
285 pfile->saved_line = pfile->line;
004cb263
NB
286}
287
288/* Restores a buffer overlaid by _cpp_overlay_buffer(). */
1a76916c
NB
289void
290_cpp_remove_overlay (pfile)
004cb263
NB
291 cpp_reader *pfile;
292{
293 cpp_buffer *buffer = pfile->buffer;
294
295 buffer->cur = buffer->saved_cur;
296 buffer->rlimit = buffer->saved_rlimit;
297 buffer->line_base = buffer->saved_line_base;
1a76916c
NB
298
299 pfile->line = pfile->saved_line;
004cb263
NB
300}
301
302/* Reads a logical line into the output buffer. Returns TRUE if there
303 is more text left in the buffer. */
304bool
1a76916c 305_cpp_read_logical_line_trad (pfile)
004cb263
NB
306 cpp_reader *pfile;
307{
974c43f1 308 cpp_buffer *buffer = pfile->buffer;
004cb263 309
974c43f1 310 do
004cb263 311 {
974c43f1 312 if (buffer->cur == buffer->rlimit)
004cb263 313 {
974c43f1
NB
314 bool stop = true;
315
316 /* Don't pop the last buffer. */
317 if (buffer->prev)
318 {
319 stop = buffer->return_at_eof;
320 _cpp_pop_buffer (pfile);
321 }
322
323 if (stop)
324 return false;
004cb263
NB
325 }
326
974c43f1
NB
327 CUR (pfile->context) = buffer->cur;
328 RLIMIT (pfile->context) = buffer->rlimit;
329 scan_out_logical_line (pfile, NULL);
330 buffer->cur = CUR (pfile->context);
004cb263 331 }
974c43f1 332 while (pfile->state.skipping);
82eda77e 333
004cb263
NB
334 return true;
335}
336
1ce676a0
NB
337/* Set up state for finding the opening '(' of a function-like
338 macro. */
339static void
340maybe_start_funlike (pfile, node, start, macro)
341 cpp_reader *pfile;
342 cpp_hashnode *node;
343 const uchar *start;
344 struct fun_macro *macro;
345{
346 unsigned int n = node->value.macro->paramc + 1;
347
348 if (macro->buff)
349 _cpp_release_buff (pfile, macro->buff);
350 macro->buff = _cpp_get_buff (pfile, n * sizeof (size_t));
351 macro->args = (size_t *) BUFF_FRONT (macro->buff);
352 macro->node = node;
1a76916c 353 macro->offset = start - pfile->out.base;
1ce676a0
NB
354 macro->argc = 0;
355
356 pfile->state.parsing_args = 1;
357}
358
359/* Save the OFFSET of the start of the next argument to MACRO. */
360static void
361save_argument (macro, offset)
362 struct fun_macro *macro;
363 size_t offset;
364{
365 macro->argc++;
366 if (macro->argc <= macro->node->value.macro->paramc)
367 macro->args[macro->argc] = offset;
368}
369
004cb263
NB
370/* Copies the next logical line in the current buffer to the output
371 buffer. The output is guaranteed to terminate with a NUL
c70f6ed3
NB
372 character.
373
374 If MACRO is non-NULL, then we are scanning the replacement list of
1ce676a0 375 MACRO, and we call save_replacement_text() every time we meet an
c70f6ed3 376 argument. */
004cb263 377static void
c70f6ed3 378scan_out_logical_line (pfile, macro)
004cb263 379 cpp_reader *pfile;
c70f6ed3 380 cpp_macro *macro;
004cb263 381{
cbc69f84
NB
382 cpp_context *context;
383 const uchar *cur;
1ce676a0 384 unsigned int c, paren_depth, quote = 0;
004cb263 385 uchar *out;
1ce676a0 386 struct fun_macro fmacro;
004cb263 387
1ce676a0 388 fmacro.buff = NULL;
974c43f1
NB
389
390 start_logical_line:
391 pfile->out.cur = pfile->out.base;
392 pfile->out.first_line = pfile->line;
cbc69f84
NB
393 new_context:
394 context = pfile->context;
395 cur = CUR (context);
82eda77e 396 check_output_buffer (pfile, RLIMIT (context) - cur);
1a76916c 397 out = pfile->out.cur;
004cb263
NB
398
399 for (;;)
400 {
401 c = *cur++;
402 *out++ = c;
403
404 /* There are only a few entities we need to catch: comments,
405 identifiers, newlines, escaped newlines, # and '\0'. */
406 switch (c)
407 {
408 case '\0':
82eda77e 409 if (cur - 1 != RLIMIT (context))
004cb263 410 break;
cbc69f84
NB
411
412 /* If this is a macro's expansion, pop it. */
413 if (context->prev)
414 {
1a76916c 415 pfile->out.cur = out - 1;
cbc69f84
NB
416 _cpp_pop_context (pfile);
417 goto new_context;
418 }
419
420 /* Premature end of file. Fake a new line. */
004cb263 421 cur--;
82eda77e 422 if (!pfile->buffer->from_stage3)
004cb263 423 cpp_error (pfile, DL_PEDWARN, "no newline at end of file");
1ce676a0
NB
424 if (pfile->state.parsing_args == 2)
425 cpp_error (pfile, DL_ERROR,
426 "unterminated argument list invoking macro \"%s\"",
427 NODE_NAME (fmacro.node));
004cb263 428 pfile->line++;
1ce676a0 429 goto done;
82eda77e
NB
430
431 case '\r': case '\n':
432 cur = handle_newline (pfile, cur - 1);
1ce676a0
NB
433 if (pfile->state.parsing_args == 2)
434 {
435 /* Newlines in arguments become a space. */
436 out[-1] = ' ';
437 continue;
438 }
439 goto done;
004cb263
NB
440
441 case '"':
442 case '\'':
443 if (c == quote)
444 quote = 0;
445 else if (!quote)
446 quote = c;
447 break;
448
449 case '\\':
450 if (is_vspace (*cur))
451 out--, cur = skip_escaped_newlines (pfile, cur - 1);
452 else
453 {
454 /* Skip escaped quotes here, it's easier than above, but
455 take care to first skip escaped newlines. */
456 cur = skip_escaped_newlines (pfile, cur);
457 if (*cur == '\\' || *cur == '"' || *cur == '\'')
458 *out++ = *cur++;
459 }
460 break;
461
462 case '/':
463 /* Traditional CPP does not recognize comments within
464 literals. */
465 if (!quote)
466 {
467 cur = skip_escaped_newlines (pfile, cur);
468 if (*cur == '*')
469 out--, cur = skip_comment (pfile, cur + 1);
470 }
471 break;
472
473 case '_':
474 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
475 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
476 case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
477 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
478 case 'y': case 'z':
479 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
480 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
481 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
482 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
483 case 'Y': case 'Z':
c70f6ed3
NB
484 if (quote == 0 || macro)
485 {
486 cpp_hashnode *node;
487
1a76916c 488 pfile->out.cur = --out;
c70f6ed3
NB
489 node = lex_identifier (pfile, cur - 1);
490
1ce676a0 491 if (node->type == NT_MACRO
974c43f1 492 && !pfile->state.skipping
1ce676a0 493 && pfile->state.parsing_args != 2
974c43f1
NB
494 && !pfile->state.prevent_expansion
495 && !recursive_macro (pfile, node))
c70f6ed3 496 {
1ce676a0
NB
497 if (node->value.macro->fun_like)
498 maybe_start_funlike (pfile, node, out, &fmacro);
499 else
500 {
501 /* Remove the object-like macro's name from the
502 output, and push its replacement text. */
1a76916c 503 pfile->out.cur = out;
1ce676a0
NB
504 push_replacement_text (pfile, node);
505 goto new_context;
506 }
c70f6ed3
NB
507 }
508 else if (macro && node->arg_index)
509 {
1ce676a0
NB
510 /* Found a parameter in the replacement text of a
511 #define. Remove its name from the output. */
1a76916c 512 pfile->out.cur = out;
c70f6ed3
NB
513 save_replacement_text (pfile, macro, node->arg_index);
514 }
515
1a76916c 516 out = pfile->out.cur;
c70f6ed3
NB
517 cur = CUR (context);
518 }
004cb263
NB
519 break;
520
1ce676a0
NB
521 case '(':
522 if (quote == 0)
523 {
524 paren_depth++;
525 if (pfile->state.parsing_args == 1)
526 {
1a76916c 527 const uchar *p = pfile->out.base + fmacro.offset;
1ce676a0
NB
528
529 /* Invoke a prior function-like macro if there is only
530 white space in-between. */
531 while (is_numchar (*p))
532 p++;
533 while (is_space (*p))
534 p++;
535
536 if (p == out - 1)
537 {
538 pfile->state.parsing_args = 2;
539 paren_depth = 1;
1a76916c 540 out = pfile->out.base + fmacro.offset;
1ce676a0
NB
541 fmacro.args[0] = fmacro.offset;
542 }
543 else
544 pfile->state.parsing_args = 0;
545 }
546 }
547 break;
548
549 case ',':
550 if (quote == 0 && pfile->state.parsing_args == 2 && paren_depth == 1)
1a76916c 551 save_argument (&fmacro, out - pfile->out.base);
1ce676a0
NB
552 break;
553
554 case ')':
555 if (quote == 0)
556 {
557 paren_depth--;
558 if (pfile->state.parsing_args == 2 && paren_depth == 0)
559 {
560 cpp_macro *m = fmacro.node->value.macro;
561
562 pfile->state.parsing_args = 0;
1a76916c 563 save_argument (&fmacro, out - pfile->out.base);
1ce676a0 564
6618c5d4
NB
565 /* A single zero-length argument is no argument. */
566 if (fmacro.argc == 1
567 && m->paramc == 0
1a76916c 568 && out == pfile->out.base + 1)
6618c5d4 569 fmacro.argc = 0;
1ce676a0
NB
570
571 if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc))
572 {
573 /* Remove the macro's invocation from the
574 output, and push its replacement text. */
1a76916c 575 pfile->out.cur = (pfile->out.base
1ce676a0
NB
576 + fmacro.offset);
577 CUR (context) = cur;
578 replace_args_and_push (pfile, &fmacro);
579 goto new_context;
580 }
581 }
582 }
583 break;
584
1a76916c
NB
585 case '#':
586 /* At start of a line it's a directive. */
587 if (out - 1 == pfile->out.base && !pfile->state.in_directive)
588 {
589 /* This is a kludge. We want to have the ISO
590 preprocessor lex the next token. */
591 pfile->buffer->cur = cur;
592 if (_cpp_handle_directive (pfile, false /* indented */))
974c43f1 593 goto start_logical_line;
1a76916c
NB
594 }
595 break;
596
004cb263
NB
597 default:
598 break;
599 }
600 }
1ce676a0
NB
601
602 done:
603 out[-1] = '\0';
604 CUR (context) = cur;
1a76916c 605 pfile->out.cur = out - 1;
1ce676a0
NB
606 if (fmacro.buff)
607 _cpp_release_buff (pfile, fmacro.buff);
004cb263 608}
cbc69f84
NB
609
610/* Push a context holding the replacement text of the macro NODE on
1ce676a0
NB
611 the context stack. NODE is either object-like, or a function-like
612 macro with no arguments. */
cbc69f84
NB
613static void
614push_replacement_text (pfile, node)
615 cpp_reader *pfile;
616 cpp_hashnode *node;
617{
618 cpp_macro *macro = node->value.macro;
619
1ce676a0
NB
620 _cpp_push_text_context (pfile, node, macro->exp.text, macro->count);
621}
622
974c43f1
NB
623/* Returns TRUE if traditional macro recursion is detected. */
624static bool
625recursive_macro (pfile, node)
626 cpp_reader *pfile;
627 cpp_hashnode *node;
628{
629 bool recursing = node->flags & NODE_DISABLED;
630
631 /* Object-like macros that are already expanding are necessarily
632 recursive.
633
634 However, it is possible to have traditional function-like macros
635 that are not infinitely recursive but recurse to any given depth.
636 Further, it is easy to construct examples that get ever longer
637 until the point they stop recursing. So there is no easy way to
638 detect true recursion; instead we assume any expansion more than
639 20 deep since the first invocation of this macro must be
640 recursing. */
641 if (recursing && node->value.macro->fun_like)
642 {
643 size_t depth = 0;
644 cpp_context *context = pfile->context;
645
646 do
647 {
648 depth++;
649 if (context->macro == node && depth > 20)
650 break;
651 context = context->prev;
652 }
653 while (context);
654 recursing = context != NULL;
655 }
656
657 if (recursing)
658 cpp_error (pfile, DL_ERROR,
659 "detected recursion whilst expanding macro \"%s\"",
660 NODE_NAME (node));
661
662 return recursing;
663}
664
1ce676a0
NB
665/* Push a context holding the replacement text of the macro NODE on
666 the context stack. NODE is either object-like, or a function-like
667 macro with no arguments. */
668static void
669replace_args_and_push (pfile, fmacro)
670 cpp_reader *pfile;
671 struct fun_macro *fmacro;
672{
673 cpp_macro *macro = fmacro->node->value.macro;
674
675 if (macro->paramc == 0)
676 push_replacement_text (pfile, fmacro->node);
677 else
678 {
679 const uchar *exp;
680 uchar *p;
681 _cpp_buff *buff;
682 size_t len = 0;
683
684 /* Calculate the length of the argument-replaced text. */
685 for (exp = macro->exp.text;;)
686 {
687 struct block *b = (struct block *) exp;
688
689 len += b->text_len;
690 if (b->arg_index == 0)
691 break;
692 len += (fmacro->args[b->arg_index]
693 - fmacro->args[b->arg_index - 1] - 1);
694 exp += BLOCK_LEN (b->text_len);
695 }
696
697 /* Allocate room for the expansion plus NUL. */
698 buff = _cpp_get_buff (pfile, len + 1);
699
700 /* Copy the expansion and replace arguments. */
701 p = BUFF_FRONT (buff);
702 for (exp = macro->exp.text;;)
703 {
704 struct block *b = (struct block *) exp;
705 size_t arglen;
706
707 memcpy (p, b->text, b->text_len);
708 p += b->text_len;
709 if (b->arg_index == 0)
710 break;
711 arglen = (fmacro->args[b->arg_index]
712 - fmacro->args[b->arg_index - 1] - 1);
1a76916c 713 memcpy (p, pfile->out.base + fmacro->args[b->arg_index - 1],
1ce676a0
NB
714 arglen);
715 p += arglen;
716 exp += BLOCK_LEN (b->text_len);
717 }
718
719 /* NUL-terminate. */
720 *p = '\0';
721 _cpp_push_text_context (pfile, fmacro->node, BUFF_FRONT (buff), len);
722
723 /* So we free buffer allocation when macro is left. */
724 pfile->context->buff = buff;
725 }
cbc69f84
NB
726}
727
c70f6ed3 728/* Read and record the parameters, if any, of a function-like macro
1a76916c 729 definition. Destroys pfile->out.cur.
c70f6ed3
NB
730
731 Returns true on success, false on failure (syntax error or a
732 duplicate parameter). On success, CUR (pfile->context) is just
733 past the closing parenthesis. */
734static bool
735scan_parameters (pfile, macro)
736 cpp_reader *pfile;
737 cpp_macro *macro;
738{
739 const uchar *cur = CUR (pfile->context) + 1;
740 bool ok;
741
742 for (;;)
743 {
744 cur = skip_whitespace (pfile, cur);
745
1ce676a0 746 if (is_idstart (*cur))
c70f6ed3
NB
747 {
748 ok = false;
749 if (_cpp_save_parameter (pfile, macro, lex_identifier (pfile, cur)))
750 break;
751 cur = skip_whitespace (pfile, CUR (pfile->context));
752 if (*cur == ',')
753 {
754 cur++;
755 continue;
756 }
757 ok = (*cur == ')');
758 break;
759 }
760
761 ok = (*cur == ')' && macro->paramc == 0);
762 break;
763 }
764
765 CUR (pfile->context) = cur + (*cur == ')');
766
767 return ok;
768}
769
1a76916c 770/* Save the text from pfile->out.base to pfile->out.cur as
c70f6ed3
NB
771 the replacement text for the current macro, followed by argument
772 ARG_INDEX, with zero indicating the end of the replacement
773 text. */
774static void
775save_replacement_text (pfile, macro, arg_index)
776 cpp_reader *pfile;
777 cpp_macro *macro;
778 unsigned int arg_index;
779{
1a76916c 780 size_t len = pfile->out.cur - pfile->out.base;
c70f6ed3
NB
781 uchar *exp;
782
783 if (macro->paramc == 0)
784 {
785 /* Object-like and function-like macros without parameters
786 simply store their NUL-terminated replacement text. */
787 exp = _cpp_unaligned_alloc (pfile, len + 1);
1a76916c 788 memcpy (exp, pfile->out.base, len);
c70f6ed3
NB
789 exp[len] = '\0';
790 macro->exp.text = exp;
791 macro->count = len;
792 }
793 else
794 {
795 /* Store the text's length (unsigned int), the argument index
796 (unsigned short, base 1) and then the text. */
797 size_t blen = BLOCK_LEN (len);
798 struct block *block;
799
800 if (macro->count + blen > BUFF_ROOM (pfile->a_buff))
801 _cpp_extend_buff (pfile, &pfile->a_buff, macro->count + blen);
802
803 exp = BUFF_FRONT (pfile->a_buff);
804 block = (struct block *) (exp + macro->count);
805 macro->exp.text = exp;
806
807 /* Write out the block information. */
808 block->text_len = len;
809 block->arg_index = arg_index;
1a76916c 810 memcpy (block->text, pfile->out.base, len);
c70f6ed3
NB
811
812 /* Lex the rest into the start of the output buffer. */
1a76916c 813 pfile->out.cur = pfile->out.base;
c70f6ed3 814
1ce676a0 815 macro->count += blen;
6618c5d4
NB
816
817 /* If we've finished, commit the memory. */
818 if (arg_index == 0)
819 BUFF_FRONT (pfile->a_buff) += macro->count;
c70f6ed3
NB
820 }
821}
822
823/* Analyze and save the replacement text of a macro. Returns true on
824 success. */
cbc69f84
NB
825bool
826_cpp_create_trad_definition (pfile, macro)
827 cpp_reader *pfile;
828 cpp_macro *macro;
829{
c70f6ed3
NB
830 const uchar *cur;
831 uchar *limit;
cbc69f84 832
1a76916c
NB
833 CUR (pfile->context) = pfile->buffer->cur;
834
c70f6ed3
NB
835 /* Is this a function-like macro? */
836 if (* CUR (pfile->context) == '(')
837 {
1ce676a0
NB
838 /* Setting macro to NULL indicates an error occurred, and
839 prevents unnecessary work in scan_out_logical_line. */
c70f6ed3
NB
840 if (!scan_parameters (pfile, macro))
841 macro = NULL;
842 else
843 {
844 /* Success. Commit the parameter array. */
845 macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
846 BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
847 macro->fun_like = 1;
848 }
c70f6ed3
NB
849 }
850
1ce676a0
NB
851 /* Skip leading whitespace in the replacement text. */
852 CUR (pfile->context) = skip_whitespace (pfile, CUR (pfile->context));
853
c70f6ed3
NB
854 pfile->state.prevent_expansion++;
855 scan_out_logical_line (pfile, macro);
856 pfile->state.prevent_expansion--;
857
858 if (!macro)
859 return false;
cbc69f84
NB
860
861 /* Skip trailing white space. */
1a76916c
NB
862 cur = pfile->out.base;
863 limit = pfile->out.cur;
cbc69f84
NB
864 while (limit > cur && is_space (limit[-1]))
865 limit--;
1a76916c 866 pfile->out.cur = limit;
c70f6ed3 867 save_replacement_text (pfile, macro, 0);
cbc69f84
NB
868
869 return true;
870}
871
6618c5d4
NB
872/* Copy SRC of length LEN to DEST, but convert all contiguous
873 whitespace to a single space, provided it is not in quotes. The
874 quote currently in effect is pointed to by PQUOTE, and is updated
875 by the function. Returns the number of bytes copied. */
876static size_t
877canonicalize_text (dest, src, len, pquote)
878 uchar *dest;
879 const uchar *src;
880 size_t len;
881 uchar *pquote;
882{
883 uchar *orig_dest = dest;
884 uchar quote = *pquote;
885
886 while (len)
887 {
888 if (is_space (*src) && !quote)
889 {
890 do
891 src++, len--;
892 while (len && is_space (*src));
893 *dest++ = ' ';
894 }
895 else
896 {
897 if (*src == '\'' || *src == '"')
898 {
899 if (!quote)
900 quote = *src;
901 else if (quote == *src)
902 quote = 0;
903 }
904 *dest++ = *src++, len--;
905 }
906 }
907
908 *pquote = quote;
909 return dest - orig_dest;
910}
911
912/* Returns true if MACRO1 and MACRO2 have expansions different other
913 than in the form of their whitespace. */
914bool
915_cpp_expansions_different_trad (macro1, macro2)
afb03408 916 const cpp_macro *macro1, *macro2;
6618c5d4
NB
917{
918 uchar *p1 = xmalloc (macro1->count + macro2->count);
919 uchar *p2 = p1 + macro1->count;
920 uchar quote1 = 0, quote2;
921 bool mismatch;
922 size_t len1, len2;
923
924 if (macro1->paramc > 0)
925 {
926 const uchar *exp1 = macro1->exp.text, *exp2 = macro2->exp.text;
927
928 mismatch = true;
929 for (;;)
930 {
931 struct block *b1 = (struct block *) exp1;
932 struct block *b2 = (struct block *) exp2;
933
934 if (b1->arg_index != b2->arg_index)
935 break;
936
937 len1 = canonicalize_text (p1, b1->text, b1->text_len, &quote1);
938 len2 = canonicalize_text (p2, b2->text, b2->text_len, &quote2);
939 if (len1 != len2 || memcmp (p1, p2, len1))
940 break;
941 if (b1->arg_index == 0)
942 {
943 mismatch = false;
944 break;
945 }
946 exp1 += BLOCK_LEN (b1->text_len);
947 exp2 += BLOCK_LEN (b2->text_len);
948 }
949 }
950 else
951 {
952 len1 = canonicalize_text (p1, macro1->exp.text, macro1->count, &quote1);
953 len2 = canonicalize_text (p2, macro2->exp.text, macro2->count, &quote2);
954 mismatch = (len1 != len2 || memcmp (p1, p2, len1));
955 }
956
957 free (p1);
958 return mismatch;
959}
960
cbc69f84
NB
961/* Prepare to be able to scan the current buffer. */
962void
963_cpp_set_trad_context (pfile)
964 cpp_reader *pfile;
965{
966 cpp_buffer *buffer = pfile->buffer;
967 cpp_context *context = pfile->context;
968
969 if (pfile->context->prev)
970 abort ();
971
1a76916c 972 pfile->out.cur = pfile->out.base;
cbc69f84
NB
973 CUR (context) = buffer->cur;
974 RLIMIT (context) = buffer->rlimit;
975 check_output_buffer (pfile, RLIMIT (context) - CUR (context));
976}