1 /* CPP Library - traditional lexical analysis and macro expansion.
2 Copyright (C) 2002 Free Software Foundation, Inc.
3 Contributed by Neil Booth, May 2002
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 /* The replacement text of a function-like macro is stored as a
25 contiguous sequence of aligned blocks, each representing the text
26 between subsequent parameters in that text.
28 Each block comprises the length of text contained therein, the
29 one-based index of the argument that immediately follows that text,
30 and the text itself. The final block in the macro expansion is
31 easily recognizable as it has an argument index of zero. */
35 unsigned int text_len;
36 unsigned short arg_index;
40 #define BLOCK_HEADER_LEN offsetof (struct block, text)
41 #define BLOCK_LEN(TEXT_LEN) CPP_ALIGN (BLOCK_HEADER_LEN + (TEXT_LEN))
43 /* Structure holding information about a function-like macro
47 /* Memory buffer holding the trad_arg array. */
50 /* An array of size the number of macro parameters + 1, containing
51 the offsets of the start of each macro argument in the output
52 buffer. The argument continues until the character before the
53 start of the next one. */
56 /* The hashnode of the macro. */
59 /* The offset of the macro name in the output buffer. */
62 /* The line the macro name appeared on. */
65 /* Zero-based index of argument being currently lexed. */
69 /* Lexing state. It is mostly used to prevent macro expansion. */
70 enum ls {ls_none = 0, /* Normal state. */
71 ls_fun_open, /* When looking for '('. */
72 ls_fun_close, /* When looking for ')'. */
73 ls_defined, /* After defined. */
74 ls_defined_close, /* Looking for ')' of defined(). */
75 ls_hash, /* After # in preprocessor conditional. */
76 ls_predicate, /* After the predicate, maybe paren? */
77 ls_answer}; /* In answer to predicate. */
79 /* Lexing TODO: Maybe handle space in escaped newlines. Stop cpplex.c
80 from recognizing comments and directives during its lexing pass. */
82 static const uchar *handle_newline PARAMS ((cpp_reader *, const uchar *));
83 static const uchar *skip_escaped_newlines PARAMS ((cpp_reader *,
85 static const uchar *skip_whitespace PARAMS ((cpp_reader *, const uchar *,
87 static cpp_hashnode *lex_identifier PARAMS ((cpp_reader *, const uchar *));
88 static const uchar *copy_comment PARAMS ((cpp_reader *, const uchar *, int));
89 static void scan_out_logical_line PARAMS ((cpp_reader *pfile, cpp_macro *));
90 static void check_output_buffer PARAMS ((cpp_reader *, size_t));
91 static void push_replacement_text PARAMS ((cpp_reader *, cpp_hashnode *));
92 static bool scan_parameters PARAMS ((cpp_reader *, cpp_macro *));
93 static bool recursive_macro PARAMS ((cpp_reader *, cpp_hashnode *));
94 static void save_replacement_text PARAMS ((cpp_reader *, cpp_macro *,
96 static void maybe_start_funlike PARAMS ((cpp_reader *, cpp_hashnode *,
97 const uchar *, struct fun_macro *));
98 static void save_argument PARAMS ((struct fun_macro *, size_t));
99 static void replace_args_and_push PARAMS ((cpp_reader *, struct fun_macro *));
100 static size_t canonicalize_text PARAMS ((uchar *, const uchar *, size_t,
103 /* Ensures we have N bytes' space in the output buffer, and
104 reallocates it if not. */
106 check_output_buffer (pfile, n)
110 /* We might need two bytes to terminate an unterminated comment, and
111 one more to terminate the line with a NUL. */
114 if (n > (size_t) (pfile->out.limit - pfile->out.cur))
116 size_t size = pfile->out.cur - pfile->out.base;
117 size_t new_size = (size + n) * 3 / 2;
120 = (uchar *) xrealloc (pfile->out.base, new_size);
121 pfile->out.limit = pfile->out.base + new_size;
122 pfile->out.cur = pfile->out.base + size;
126 /* To be called whenever a newline character is encountered in the
127 input file, at CUR. Handles DOS, Mac and Unix ends of line, and
128 increments pfile->line.
130 Returns a pointer the character after the newline sequence. */
132 handle_newline (pfile, cur)
137 if (cur[0] + cur[1] == '\r' + '\n')
142 /* CUR points to any character in the buffer, not necessarily a
143 backslash. Advances CUR until all escaped newlines are skipped,
144 and returns the new position.
146 Warns if a file buffer ends in an escaped newline. */
148 skip_escaped_newlines (pfile, cur)
152 const uchar *orig_cur = cur;
154 while (*cur == '\\' && is_vspace (cur[1]))
155 cur = handle_newline (pfile, cur + 1);
157 if (cur != orig_cur && cur == RLIMIT (pfile->context) && pfile->buffer->inc)
158 cpp_error (pfile, DL_PEDWARN, "backslash-newline at end of file");
163 /* CUR points to the asterisk introducing a comment in the input
164 buffer. IN_DEFINE is true if we are in the replacement text
167 The asterisk and following comment is copied to the buffer pointed
168 to by pfile->out.cur, which must be of sufficient size.
169 Unterminated comments are diagnosed, and correctly terminated in
170 the output. pfile->out.cur is updated depending upon IN_DEFINE,
171 -C, -CC and pfile->state.in_directive.
173 Returns a pointer to the first character after the comment in the
176 copy_comment (pfile, cur, in_define)
181 unsigned int from_line = pfile->line;
182 const uchar *limit = RLIMIT (pfile->context);
183 uchar *out = pfile->out.cur;
187 unsigned int c = *cur++;
192 /* An immediate slash does not terminate the comment. */
193 if (out[-2] == '*' && out - 2 > pfile->out.cur)
196 if (*cur == '*' && cur[1] != '/'
197 && CPP_OPTION (pfile, warn_comments))
198 cpp_error_with_line (pfile, DL_WARNING, pfile->line, 0,
199 "\"/*\" within comment");
201 else if (is_vspace (c))
203 cur = handle_newline (pfile, cur - 1);
204 /* Canonicalize newline sequences and skip escaped ones. */
213 cpp_error_with_line (pfile, DL_ERROR, from_line, 0, "unterminated comment");
218 /* Comments in directives become spaces so that tokens are properly
219 separated when the ISO preprocessor re-lexes the line. The
220 exception is #define. */
221 if (pfile->state.in_directive)
225 if (CPP_OPTION (pfile, discard_comments_in_macro_exp))
228 pfile->out.cur = out;
231 pfile->out.cur[-1] = ' ';
233 else if (CPP_OPTION (pfile, discard_comments))
236 pfile->out.cur = out;
241 /* CUR points to any character in the input buffer. Skips over all
242 contiguous horizontal white space and NULs, including comments if
243 SKIP_COMMENTS, until reaching the first non-horizontal-whitespace
244 character or the end of the current context. Escaped newlines are
247 The whitespace is copied verbatim to the output buffer, except that
248 comments are handled as described in copy_comment().
249 pfile->out.cur is updated.
251 Returns a pointer to the first character after the whitespace in
254 skip_whitespace (pfile, cur, skip_comments)
259 uchar *out = pfile->out.cur;
263 unsigned int c = *cur++;
266 if (is_nvspace (c) && c)
269 if (!c && cur - 1 != RLIMIT (pfile->context))
272 if (c == '/' && skip_comments)
274 const uchar *tmp = skip_escaped_newlines (pfile, cur);
277 pfile->out.cur = out;
278 cur = copy_comment (pfile, tmp, false /* in_define */);
279 out = pfile->out.cur;
285 if (c == '\\' && is_vspace (*cur))
287 cur = skip_escaped_newlines (pfile, cur);
294 pfile->out.cur = out;
298 /* Lexes and outputs an identifier starting at CUR, which is assumed
299 to point to a valid first character of an identifier. Returns
300 the hashnode, and updates out.cur. */
301 static cpp_hashnode *
302 lex_identifier (pfile, cur)
307 uchar *out = pfile->out.cur;
308 cpp_hashnode *result;
314 while (is_numchar (*cur));
315 cur = skip_escaped_newlines (pfile, cur);
317 while (is_numchar (*cur));
319 CUR (pfile->context) = cur;
320 len = out - pfile->out.cur;
321 result = (cpp_hashnode *) ht_lookup (pfile->hash_table, pfile->out.cur,
323 pfile->out.cur = out;
327 /* Overlays the true file buffer temporarily with text of length LEN
328 starting at START. The true buffer is restored upon calling
331 _cpp_overlay_buffer (pfile, start, len)
336 cpp_buffer *buffer = pfile->buffer;
338 pfile->overlaid_buffer = buffer;
339 buffer->saved_cur = buffer->cur;
340 buffer->saved_rlimit = buffer->rlimit;
343 buffer->rlimit = start + len;
345 pfile->saved_line = pfile->line;
348 /* Restores a buffer overlaid by _cpp_overlay_buffer(). */
350 _cpp_remove_overlay (pfile)
353 cpp_buffer *buffer = pfile->overlaid_buffer;
355 buffer->cur = buffer->saved_cur;
356 buffer->rlimit = buffer->saved_rlimit;
358 pfile->line = pfile->saved_line;
361 /* Reads a logical line into the output buffer. Returns TRUE if there
362 is more text left in the buffer. */
364 _cpp_read_logical_line_trad (pfile)
367 cpp_buffer *buffer = pfile->buffer;
371 if (buffer->cur == buffer->rlimit)
375 /* Don't pop the last buffer. */
378 stop = buffer->return_at_eof;
379 _cpp_pop_buffer (pfile);
380 buffer = pfile->buffer;
387 CUR (pfile->context) = buffer->cur;
388 RLIMIT (pfile->context) = buffer->rlimit;
389 scan_out_logical_line (pfile, NULL);
390 buffer = pfile->buffer;
391 buffer->cur = CUR (pfile->context);
393 while (pfile->state.skipping);
398 /* Set up state for finding the opening '(' of a function-like
401 maybe_start_funlike (pfile, node, start, macro)
405 struct fun_macro *macro;
407 unsigned int n = node->value.macro->paramc + 1;
410 _cpp_release_buff (pfile, macro->buff);
411 macro->buff = _cpp_get_buff (pfile, n * sizeof (size_t));
412 macro->args = (size_t *) BUFF_FRONT (macro->buff);
414 macro->offset = start - pfile->out.base;
418 /* Save the OFFSET of the start of the next argument to MACRO. */
420 save_argument (macro, offset)
421 struct fun_macro *macro;
425 if (macro->argc <= macro->node->value.macro->paramc)
426 macro->args[macro->argc] = offset;
429 /* Copies the next logical line in the current buffer to the output
430 buffer. The output is guaranteed to terminate with a NUL
433 If MACRO is non-NULL, then we are scanning the replacement list of
434 MACRO, and we call save_replacement_text() every time we meet an
437 scan_out_logical_line (pfile, macro)
441 cpp_context *context;
444 struct fun_macro fmacro;
445 unsigned int c, paren_depth = 0, quote = 0;
446 enum ls lex_state = ls_none;
451 pfile->out.cur = pfile->out.base;
452 pfile->out.first_line = pfile->line;
454 context = pfile->context;
456 check_output_buffer (pfile, RLIMIT (context) - cur);
457 out = pfile->out.cur;
464 /* Whitespace should "continue" out of the switch,
465 non-whitespace should "break" out of it. */
475 if (cur - 1 != RLIMIT (context))
478 /* If this is a macro's expansion, pop it. */
481 pfile->out.cur = out - 1;
482 _cpp_pop_context (pfile);
486 /* Premature end of file. Fake a new line. */
488 if (!pfile->buffer->from_stage3)
489 cpp_error (pfile, DL_PEDWARN, "no newline at end of file");
493 case '\r': case '\n':
494 cur = handle_newline (pfile, cur - 1);
495 if ((lex_state == ls_fun_open || lex_state == ls_fun_close)
496 && !pfile->state.in_directive)
498 /* Newlines in arguments become a space. */
499 if (lex_state == ls_fun_close)
506 if (pfile->state.angled_headers && !quote)
510 if (pfile->state.angled_headers && c == quote)
512 pfile->state.angled_headers = false;
526 if (is_vspace (*cur))
529 cur = skip_escaped_newlines (pfile, cur - 1);
534 /* Skip escaped quotes here, it's easier than above, but
535 take care to first skip escaped newlines. */
536 cur = skip_escaped_newlines (pfile, cur);
537 if (*cur == '\\' || *cur == '"' || *cur == '\'')
543 /* Traditional CPP does not recognize comments within
547 cur = skip_escaped_newlines (pfile, cur);
550 pfile->out.cur = out;
551 cur = copy_comment (pfile, cur, macro != 0);
552 out = pfile->out.cur;
559 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
560 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
561 case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
562 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
564 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
565 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
566 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
567 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
569 if (!pfile->state.skipping && (quote == 0 || macro))
572 uchar *out_start = out - 1;
574 pfile->out.cur = out_start;
575 node = lex_identifier (pfile, cur - 1);
576 out = pfile->out.cur;
579 if (node->type == NT_MACRO
580 /* Should we expand for ls_answer? */
581 && (lex_state == ls_none || lex_state == ls_fun_open)
582 && !pfile->state.prevent_expansion
583 && !recursive_macro (pfile, node))
585 /* Macros invalidate MI optimization. */
586 pfile->mi_valid = false;
587 if (! (node->flags & NODE_BUILTIN)
588 && node->value.macro->fun_like)
590 maybe_start_funlike (pfile, node, out_start, &fmacro);
591 lex_state = ls_fun_open;
592 fmacro.line = pfile->line;
597 /* Remove the object-like macro's name from the
598 output, and push its replacement text. */
599 pfile->out.cur = out_start;
600 push_replacement_text (pfile, node);
605 else if (macro && node->arg_index)
607 /* Found a parameter in the replacement text of a
608 #define. Remove its name from the output. */
609 pfile->out.cur = out_start;
610 save_replacement_text (pfile, macro, node->arg_index);
611 out = pfile->out.base;
613 else if (lex_state == ls_hash)
615 lex_state = ls_predicate;
618 else if (pfile->state.in_expression
619 && node == pfile->spec_nodes.n_defined)
621 lex_state = ls_defined;
631 if (lex_state == ls_fun_open)
633 lex_state = ls_fun_close;
635 out = pfile->out.base + fmacro.offset;
636 fmacro.args[0] = fmacro.offset;
638 else if (lex_state == ls_predicate)
639 lex_state = ls_answer;
640 else if (lex_state == ls_defined)
641 lex_state = ls_defined_close;
646 if (quote == 0 && lex_state == ls_fun_close && paren_depth == 1)
647 save_argument (&fmacro, out - pfile->out.base);
654 if (lex_state == ls_fun_close && paren_depth == 0)
656 cpp_macro *m = fmacro.node->value.macro;
659 save_argument (&fmacro, out - pfile->out.base);
661 /* A single zero-length argument is no argument. */
664 && out == pfile->out.base + fmacro.offset + 1)
667 if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc))
669 /* Remove the macro's invocation from the
670 output, and push its replacement text. */
671 pfile->out.cur = (pfile->out.base
674 replace_args_and_push (pfile, &fmacro);
678 else if (lex_state == ls_answer || lex_state == ls_defined_close)
684 /* At start of a line it's a directive. */
685 if (out - 1 == pfile->out.base && !pfile->state.in_directive)
687 /* This is a kludge. We want to have the ISO
688 preprocessor lex the next token. */
689 pfile->buffer->cur = cur;
690 if (_cpp_handle_directive (pfile, false /* indented */))
691 goto start_logical_line;
693 if (pfile->state.in_expression)
704 if (lex_state == ls_none)
707 /* Some of these transitions of state are syntax errors. The
708 ISO preprocessor will issue errors later. */
709 if (lex_state == ls_fun_open)
712 else if (lex_state == ls_hash
713 || lex_state == ls_predicate
714 || lex_state == ls_defined)
717 /* ls_answer and ls_defined_close keep going until ')'. */
723 pfile->out.cur = out - 1;
725 _cpp_release_buff (pfile, fmacro.buff);
727 if (lex_state == ls_fun_close)
728 cpp_error_with_line (pfile, DL_ERROR, fmacro.line, 0,
729 "unterminated argument list invoking macro \"%s\"",
730 NODE_NAME (fmacro.node));
733 /* Push a context holding the replacement text of the macro NODE on
734 the context stack. NODE is either object-like, or a function-like
735 macro with no arguments. */
737 push_replacement_text (pfile, node)
744 if (node->flags & NODE_BUILTIN)
746 text = _cpp_builtin_macro_text (pfile, node);
747 len = ustrlen (text);
751 cpp_macro *macro = node->value.macro;
752 text = macro->exp.text;
756 _cpp_push_text_context (pfile, node, text, len);
759 /* Returns TRUE if traditional macro recursion is detected. */
761 recursive_macro (pfile, node)
765 bool recursing = node->flags & NODE_DISABLED;
767 /* Object-like macros that are already expanding are necessarily
770 However, it is possible to have traditional function-like macros
771 that are not infinitely recursive but recurse to any given depth.
772 Further, it is easy to construct examples that get ever longer
773 until the point they stop recursing. So there is no easy way to
774 detect true recursion; instead we assume any expansion more than
775 20 deep since the first invocation of this macro must be
777 if (recursing && node->value.macro->fun_like)
780 cpp_context *context = pfile->context;
785 if (context->macro == node && depth > 20)
787 context = context->prev;
790 recursing = context != NULL;
794 cpp_error (pfile, DL_ERROR,
795 "detected recursion whilst expanding macro \"%s\"",
801 /* Return the length of the replacement text of a function-like or
802 object-like non-builtin macro. */
804 _cpp_replacement_text_len (macro)
805 const cpp_macro *macro;
814 for (exp = macro->exp.text;;)
816 struct block *b = (struct block *) exp;
819 if (b->arg_index == 0)
821 len += NODE_LEN (macro->params[b->arg_index - 1]);
822 exp += BLOCK_LEN (b->text_len);
831 /* Copy the replacement text of MACRO to DEST, which must be of
832 sufficient size. It is not NUL-terminated. The next character is
835 _cpp_copy_replacement_text (macro, dest)
836 const cpp_macro *macro;
843 for (exp = macro->exp.text;;)
845 struct block *b = (struct block *) exp;
848 memcpy (dest, b->text, b->text_len);
850 if (b->arg_index == 0)
852 param = macro->params[b->arg_index - 1];
853 memcpy (dest, NODE_NAME (param), NODE_LEN (param));
854 dest += NODE_LEN (param);
855 exp += BLOCK_LEN (b->text_len);
860 memcpy (dest, macro->exp.text, macro->count);
861 dest += macro->count;
867 /* Push a context holding the replacement text of the macro NODE on
868 the context stack. NODE is either object-like, or a function-like
869 macro with no arguments. */
871 replace_args_and_push (pfile, fmacro)
873 struct fun_macro *fmacro;
875 cpp_macro *macro = fmacro->node->value.macro;
877 if (macro->paramc == 0)
878 push_replacement_text (pfile, fmacro->node);
886 /* Calculate the length of the argument-replaced text. */
887 for (exp = macro->exp.text;;)
889 struct block *b = (struct block *) exp;
892 if (b->arg_index == 0)
894 len += (fmacro->args[b->arg_index]
895 - fmacro->args[b->arg_index - 1] - 1);
896 exp += BLOCK_LEN (b->text_len);
899 /* Allocate room for the expansion plus NUL. */
900 buff = _cpp_get_buff (pfile, len + 1);
902 /* Copy the expansion and replace arguments. */
903 p = BUFF_FRONT (buff);
904 for (exp = macro->exp.text;;)
906 struct block *b = (struct block *) exp;
909 memcpy (p, b->text, b->text_len);
911 if (b->arg_index == 0)
913 arglen = (fmacro->args[b->arg_index]
914 - fmacro->args[b->arg_index - 1] - 1);
915 memcpy (p, pfile->out.base + fmacro->args[b->arg_index - 1],
918 exp += BLOCK_LEN (b->text_len);
923 _cpp_push_text_context (pfile, fmacro->node, BUFF_FRONT (buff), len);
925 /* So we free buffer allocation when macro is left. */
926 pfile->context->buff = buff;
930 /* Read and record the parameters, if any, of a function-like macro
931 definition. Destroys pfile->out.cur.
933 Returns true on success, false on failure (syntax error or a
934 duplicate parameter). On success, CUR (pfile->context) is just
935 past the closing parenthesis. */
937 scan_parameters (pfile, macro)
941 const uchar *cur = CUR (pfile->context) + 1;
946 cur = skip_whitespace (pfile, cur, true /* skip_comments */);
948 if (is_idstart (*cur))
951 if (_cpp_save_parameter (pfile, macro, lex_identifier (pfile, cur)))
953 cur = skip_whitespace (pfile, CUR (pfile->context),
954 true /* skip_comments */);
964 ok = (*cur == ')' && macro->paramc == 0);
968 CUR (pfile->context) = cur + (*cur == ')');
973 /* Save the text from pfile->out.base to pfile->out.cur as
974 the replacement text for the current macro, followed by argument
975 ARG_INDEX, with zero indicating the end of the replacement
978 save_replacement_text (pfile, macro, arg_index)
981 unsigned int arg_index;
983 size_t len = pfile->out.cur - pfile->out.base;
986 if (macro->paramc == 0)
988 /* Object-like and function-like macros without parameters
989 simply store their NUL-terminated replacement text. */
990 exp = _cpp_unaligned_alloc (pfile, len + 1);
991 memcpy (exp, pfile->out.base, len);
993 macro->exp.text = exp;
998 /* Store the text's length (unsigned int), the argument index
999 (unsigned short, base 1) and then the text. */
1000 size_t blen = BLOCK_LEN (len);
1001 struct block *block;
1003 if (macro->count + blen > BUFF_ROOM (pfile->a_buff))
1004 _cpp_extend_buff (pfile, &pfile->a_buff, macro->count + blen);
1006 exp = BUFF_FRONT (pfile->a_buff);
1007 block = (struct block *) (exp + macro->count);
1008 macro->exp.text = exp;
1010 /* Write out the block information. */
1011 block->text_len = len;
1012 block->arg_index = arg_index;
1013 memcpy (block->text, pfile->out.base, len);
1015 /* Lex the rest into the start of the output buffer. */
1016 pfile->out.cur = pfile->out.base;
1018 macro->count += blen;
1020 /* If we've finished, commit the memory. */
1022 BUFF_FRONT (pfile->a_buff) += macro->count;
1026 /* Analyze and save the replacement text of a macro. Returns true on
1029 _cpp_create_trad_definition (pfile, macro)
1036 CUR (pfile->context) = pfile->buffer->cur;
1038 /* Is this a function-like macro? */
1039 if (* CUR (pfile->context) == '(')
1041 /* Setting macro to NULL indicates an error occurred, and
1042 prevents unnecessary work in scan_out_logical_line. */
1043 if (!scan_parameters (pfile, macro))
1047 /* Success. Commit the parameter array. */
1048 macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
1049 BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc];
1050 macro->fun_like = 1;
1054 /* Skip leading whitespace in the replacement text. */
1055 CUR (pfile->context)
1056 = skip_whitespace (pfile, CUR (pfile->context),
1057 CPP_OPTION (pfile, discard_comments_in_macro_exp));
1059 pfile->state.prevent_expansion++;
1060 scan_out_logical_line (pfile, macro);
1061 pfile->state.prevent_expansion--;
1066 /* Skip trailing white space. */
1067 cur = pfile->out.base;
1068 limit = pfile->out.cur;
1069 while (limit > cur && is_space (limit[-1]))
1071 pfile->out.cur = limit;
1072 save_replacement_text (pfile, macro, 0);
1077 /* Copy SRC of length LEN to DEST, but convert all contiguous
1078 whitespace to a single space, provided it is not in quotes. The
1079 quote currently in effect is pointed to by PQUOTE, and is updated
1080 by the function. Returns the number of bytes copied. */
1082 canonicalize_text (dest, src, len, pquote)
1088 uchar *orig_dest = dest;
1089 uchar quote = *pquote;
1093 if (is_space (*src) && !quote)
1097 while (len && is_space (*src));
1102 if (*src == '\'' || *src == '"')
1106 else if (quote == *src)
1109 *dest++ = *src++, len--;
1114 return dest - orig_dest;
1117 /* Returns true if MACRO1 and MACRO2 have expansions different other
1118 than in the form of their whitespace. */
1120 _cpp_expansions_different_trad (macro1, macro2)
1121 const cpp_macro *macro1, *macro2;
1123 uchar *p1 = xmalloc (macro1->count + macro2->count);
1124 uchar *p2 = p1 + macro1->count;
1125 uchar quote1 = 0, quote2 = 0;
1129 if (macro1->paramc > 0)
1131 const uchar *exp1 = macro1->exp.text, *exp2 = macro2->exp.text;
1136 struct block *b1 = (struct block *) exp1;
1137 struct block *b2 = (struct block *) exp2;
1139 if (b1->arg_index != b2->arg_index)
1142 len1 = canonicalize_text (p1, b1->text, b1->text_len, "e1);
1143 len2 = canonicalize_text (p2, b2->text, b2->text_len, "e2);
1144 if (len1 != len2 || memcmp (p1, p2, len1))
1146 if (b1->arg_index == 0)
1151 exp1 += BLOCK_LEN (b1->text_len);
1152 exp2 += BLOCK_LEN (b2->text_len);
1157 len1 = canonicalize_text (p1, macro1->exp.text, macro1->count, "e1);
1158 len2 = canonicalize_text (p2, macro2->exp.text, macro2->count, "e2);
1159 mismatch = (len1 != len2 || memcmp (p1, p2, len1));
1166 /* Prepare to be able to scan the current buffer. */
1168 _cpp_set_trad_context (pfile)
1171 cpp_buffer *buffer = pfile->buffer;
1172 cpp_context *context = pfile->context;
1174 if (pfile->context->prev)
1177 pfile->out.cur = pfile->out.base;
1178 CUR (context) = buffer->cur;
1179 RLIMIT (context) = buffer->rlimit;
1180 check_output_buffer (pfile, RLIMIT (context) - CUR (context));