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. */
21 #include "coretypes.h"
26 /* The replacement text of a function-like macro is stored as a
27 contiguous sequence of aligned blocks, each representing the text
28 between subsequent parameters.
30 Each block comprises the text between its surrounding parameters,
31 the length of that text, and the one-based index of the following
32 parameter. The final block in the replacement text is easily
33 recognizable as it has an argument index of zero. */
37 unsigned int text_len;
38 unsigned short arg_index;
42 #define BLOCK_HEADER_LEN offsetof (struct block, text)
43 #define BLOCK_LEN(TEXT_LEN) CPP_ALIGN (BLOCK_HEADER_LEN + (TEXT_LEN))
45 /* Structure holding information about a function-like macro
49 /* Memory buffer holding the trad_arg array. */
52 /* An array of size the number of macro parameters + 1, containing
53 the offsets of the start of each macro argument in the output
54 buffer. The argument continues until the character before the
55 start of the next one. */
58 /* The hashnode of the macro. */
61 /* The offset of the macro name in the output buffer. */
64 /* The line the macro name appeared on. */
67 /* Zero-based index of argument being currently lexed. */
71 /* Lexing state. It is mostly used to prevent macro expansion. */
72 enum ls {ls_none = 0, /* Normal state. */
73 ls_fun_open, /* When looking for '('. */
74 ls_fun_close, /* When looking for ')'. */
75 ls_defined, /* After defined. */
76 ls_defined_close, /* Looking for ')' of defined(). */
77 ls_hash, /* After # in preprocessor conditional. */
78 ls_predicate, /* After the predicate, maybe paren? */
79 ls_answer}; /* In answer to predicate. */
81 /* Lexing TODO: Maybe handle space in escaped newlines. Stop cpplex.c
82 from recognizing comments and directives during its lexing pass. */
84 static const uchar *skip_whitespace PARAMS ((cpp_reader *, const uchar *,
86 static cpp_hashnode *lex_identifier PARAMS ((cpp_reader *, const uchar *));
87 static const uchar *copy_comment PARAMS ((cpp_reader *, const uchar *, int));
88 static void check_output_buffer PARAMS ((cpp_reader *, size_t));
89 static void push_replacement_text PARAMS ((cpp_reader *, cpp_hashnode *));
90 static bool scan_parameters PARAMS ((cpp_reader *, cpp_macro *));
91 static bool recursive_macro PARAMS ((cpp_reader *, cpp_hashnode *));
92 static void save_replacement_text PARAMS ((cpp_reader *, cpp_macro *,
94 static void maybe_start_funlike PARAMS ((cpp_reader *, cpp_hashnode *,
95 const uchar *, struct fun_macro *));
96 static void save_argument PARAMS ((struct fun_macro *, size_t));
97 static void replace_args_and_push PARAMS ((cpp_reader *, struct fun_macro *));
98 static size_t canonicalize_text PARAMS ((uchar *, const uchar *, size_t,
101 /* Ensures we have N bytes' space in the output buffer, and
102 reallocates it if not. */
104 check_output_buffer (pfile, n)
108 /* We might need two bytes to terminate an unterminated comment, and
109 one more to terminate the line with a NUL. */
112 if (n > (size_t) (pfile->out.limit - pfile->out.cur))
114 size_t size = pfile->out.cur - pfile->out.base;
115 size_t new_size = (size + n) * 3 / 2;
118 = (uchar *) xrealloc (pfile->out.base, new_size);
119 pfile->out.limit = pfile->out.base + new_size;
120 pfile->out.cur = pfile->out.base + size;
124 /* CUR points to the asterisk introducing a comment in the current
125 context. IN_DEFINE is true if we are in the replacement text of a
128 The asterisk and following comment is copied to the buffer pointed
129 to by pfile->out.cur, which must be of sufficient size.
130 Unterminated comments are diagnosed, and correctly terminated in
131 the output. pfile->out.cur is updated depending upon IN_DEFINE,
132 -C, -CC and pfile->state.in_directive.
134 Returns a pointer to the first character after the comment in the
137 copy_comment (pfile, cur, in_define)
142 bool unterminated, copy = false;
143 unsigned int from_line = pfile->line;
144 cpp_buffer *buffer = pfile->buffer;
147 unterminated = _cpp_skip_block_comment (pfile);
149 cpp_error_with_line (pfile, DL_ERROR, from_line, 0,
150 "unterminated comment");
152 /* Comments in directives become spaces so that tokens are properly
153 separated when the ISO preprocessor re-lexes the line. The
154 exception is #define. */
155 if (pfile->state.in_directive)
159 if (CPP_OPTION (pfile, discard_comments_in_macro_exp))
165 pfile->out.cur[-1] = ' ';
167 else if (CPP_OPTION (pfile, discard_comments))
174 size_t len = (size_t) (buffer->cur - cur);
175 memcpy (pfile->out.cur, cur, len);
176 pfile->out.cur += len;
179 *pfile->out.cur++ = '*';
180 *pfile->out.cur++ = '/';
187 /* CUR points to any character in the input buffer. Skips over all
188 contiguous horizontal white space and NULs, including comments if
189 SKIP_COMMENTS, until reaching the first non-horizontal-whitespace
190 character or the end of the current context. Escaped newlines are
193 The whitespace is copied verbatim to the output buffer, except that
194 comments are handled as described in copy_comment().
195 pfile->out.cur is updated.
197 Returns a pointer to the first character after the whitespace in
200 skip_whitespace (pfile, cur, skip_comments)
205 uchar *out = pfile->out.cur;
209 unsigned int c = *cur++;
215 if (c == '/' && *cur == '*' && skip_comments)
217 pfile->out.cur = out;
218 cur = copy_comment (pfile, cur, false /* in_define */);
219 out = pfile->out.cur;
227 pfile->out.cur = out;
231 /* Lexes and outputs an identifier starting at CUR, which is assumed
232 to point to a valid first character of an identifier. Returns
233 the hashnode, and updates out.cur. */
234 static cpp_hashnode *
235 lex_identifier (pfile, cur)
240 uchar *out = pfile->out.cur;
241 cpp_hashnode *result;
245 while (is_numchar (*cur));
247 CUR (pfile->context) = cur;
248 len = out - pfile->out.cur;
249 result = (cpp_hashnode *) ht_lookup (pfile->hash_table, pfile->out.cur,
251 pfile->out.cur = out;
255 /* Overlays the true file buffer temporarily with text of length LEN
256 starting at START. The true buffer is restored upon calling
259 _cpp_overlay_buffer (pfile, start, len)
264 cpp_buffer *buffer = pfile->buffer;
266 pfile->overlaid_buffer = buffer;
267 buffer->saved_cur = buffer->cur;
268 buffer->saved_rlimit = buffer->rlimit;
269 /* Prevent the ISO lexer from scanning a fresh line. */
270 pfile->saved_line = pfile->line--;
271 buffer->need_line = false;
274 buffer->rlimit = start + len;
277 /* Restores a buffer overlaid by _cpp_overlay_buffer(). */
279 _cpp_remove_overlay (pfile)
282 cpp_buffer *buffer = pfile->overlaid_buffer;
284 buffer->cur = buffer->saved_cur;
285 buffer->rlimit = buffer->saved_rlimit;
286 buffer->need_line = true;
288 pfile->overlaid_buffer = NULL;
289 pfile->line = pfile->saved_line;
292 /* Reads a logical line into the output buffer. Returns TRUE if there
293 is more text left in the buffer. */
295 _cpp_read_logical_line_trad (pfile)
300 if (pfile->buffer->need_line && !_cpp_get_fresh_line (pfile))
303 while (!scan_out_logical_line (pfile, NULL) || pfile->state.skipping);
308 /* Set up state for finding the opening '(' of a function-like
311 maybe_start_funlike (pfile, node, start, macro)
315 struct fun_macro *macro;
317 unsigned int n = node->value.macro->paramc + 1;
320 _cpp_release_buff (pfile, macro->buff);
321 macro->buff = _cpp_get_buff (pfile, n * sizeof (size_t));
322 macro->args = (size_t *) BUFF_FRONT (macro->buff);
324 macro->offset = start - pfile->out.base;
328 /* Save the OFFSET of the start of the next argument to MACRO. */
330 save_argument (macro, offset)
331 struct fun_macro *macro;
335 if (macro->argc <= macro->node->value.macro->paramc)
336 macro->args[macro->argc] = offset;
339 /* Copies the next logical line in the current buffer (starting at
340 buffer->cur) to the output buffer. The output is guaranteed to
341 terminate with a NUL character. buffer->cur is updated.
343 If MACRO is non-NULL, then we are scanning the replacement list of
344 MACRO, and we call save_replacement_text() every time we meet an
347 scan_out_logical_line (pfile, macro)
352 cpp_context *context;
355 struct fun_macro fmacro;
356 unsigned int c, paren_depth = 0, quote;
357 enum ls lex_state = ls_none;
363 header_ok = pfile->state.angled_headers;
364 CUR (pfile->context) = pfile->buffer->cur;
365 RLIMIT (pfile->context) = pfile->buffer->rlimit;
366 pfile->out.cur = pfile->out.base;
367 pfile->out.first_line = pfile->line;
369 context = pfile->context;
371 check_output_buffer (pfile, RLIMIT (context) - cur);
372 out = pfile->out.cur;
377 && cur >= pfile->buffer->notes[pfile->buffer->cur_note].pos)
379 pfile->buffer->cur = cur;
380 _cpp_process_line_notes (pfile, false);
385 /* Whitespace should "continue" out of the switch,
386 non-whitespace should "break" out of it. */
397 /* If this is a macro's expansion, pop it. */
400 pfile->out.cur = out - 1;
401 _cpp_pop_context (pfile);
405 /* Omit the newline from the output buffer. */
406 pfile->out.cur = out - 1;
407 pfile->buffer->cur = cur;
408 pfile->buffer->need_line = true;
411 if ((lex_state == ls_fun_open || lex_state == ls_fun_close)
412 && !pfile->state.in_directive
413 && _cpp_get_fresh_line (pfile))
415 /* Newlines in arguments become a space, but we don't
416 clear any in-progress quote. */
417 if (lex_state == ls_fun_close)
419 cur = pfile->buffer->cur;
442 /* Skip escaped quotes here, it's easier than above. */
443 if (*cur == '\\' || *cur == '"' || *cur == '\'')
448 /* Traditional CPP does not recognize comments within
450 if (!quote && *cur == '*')
452 pfile->out.cur = out;
453 cur = copy_comment (pfile, cur, macro != 0);
454 out = pfile->out.cur;
460 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
461 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
462 case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
463 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
465 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
466 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
467 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
468 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
470 if (!pfile->state.skipping && (quote == 0 || macro))
473 uchar *out_start = out - 1;
475 pfile->out.cur = out_start;
476 node = lex_identifier (pfile, cur - 1);
477 out = pfile->out.cur;
480 if (node->type == NT_MACRO
481 /* Should we expand for ls_answer? */
482 && (lex_state == ls_none || lex_state == ls_fun_open)
483 && !pfile->state.prevent_expansion)
485 /* Macros invalidate MI optimization. */
486 pfile->mi_valid = false;
487 if (! (node->flags & NODE_BUILTIN)
488 && node->value.macro->fun_like)
490 maybe_start_funlike (pfile, node, out_start, &fmacro);
491 lex_state = ls_fun_open;
492 fmacro.line = pfile->line;
495 else if (!recursive_macro (pfile, node))
497 /* Remove the object-like macro's name from the
498 output, and push its replacement text. */
499 pfile->out.cur = out_start;
500 push_replacement_text (pfile, node);
505 else if (macro && (node->flags & NODE_MACRO_ARG) != 0)
507 /* Found a parameter in the replacement text of a
508 #define. Remove its name from the output. */
509 pfile->out.cur = out_start;
510 save_replacement_text (pfile, macro, node->value.arg_index);
511 out = pfile->out.base;
513 else if (lex_state == ls_hash)
515 lex_state = ls_predicate;
518 else if (pfile->state.in_expression
519 && node == pfile->spec_nodes.n_defined)
521 lex_state = ls_defined;
531 if (lex_state == ls_fun_open)
533 if (recursive_macro (pfile, fmacro.node))
537 lex_state = ls_fun_close;
539 out = pfile->out.base + fmacro.offset;
540 fmacro.args[0] = fmacro.offset;
543 else if (lex_state == ls_predicate)
544 lex_state = ls_answer;
545 else if (lex_state == ls_defined)
546 lex_state = ls_defined_close;
551 if (quote == 0 && lex_state == ls_fun_close && paren_depth == 1)
552 save_argument (&fmacro, out - pfile->out.base);
559 if (lex_state == ls_fun_close && paren_depth == 0)
561 cpp_macro *m = fmacro.node->value.macro;
565 save_argument (&fmacro, out - pfile->out.base);
567 /* A single zero-length argument is no argument. */
570 && out == pfile->out.base + fmacro.offset + 1)
573 if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc))
575 /* Remove the macro's invocation from the
576 output, and push its replacement text. */
577 pfile->out.cur = (pfile->out.base
580 replace_args_and_push (pfile, &fmacro);
584 else if (lex_state == ls_answer || lex_state == ls_defined_close)
590 if (out - 1 == pfile->out.base
591 /* A '#' from a macro doesn't start a directive. */
592 && !pfile->context->prev
593 && !pfile->state.in_directive)
595 /* A directive. With the way _cpp_handle_directive
596 currently works, we only want to call it if either we
597 know the directive is OK, or we want it to fail and
598 be removed from the output. If we want it to be
599 passed through (the assembler case) then we must not
600 call _cpp_handle_directive. */
601 pfile->out.cur = out;
602 cur = skip_whitespace (pfile, cur, true /* skip_comments */);
603 out = pfile->out.cur;
607 /* Null directive. Ignore it and don't invalidate
608 the MI optimization. */
609 pfile->buffer->need_line = true;
618 if (is_numstart (*cur)
619 && CPP_OPTION (pfile, lang) != CLK_ASM)
621 else if (is_idstart (*cur))
622 /* Check whether we know this directive, but don't
624 do_it = lex_identifier (pfile, cur)->is_directive;
626 if (do_it || CPP_OPTION (pfile, lang) != CLK_ASM)
628 /* This is a kludge. We want to have the ISO
629 preprocessor lex the next token. */
630 pfile->buffer->cur = cur;
631 _cpp_handle_directive (pfile, false /* indented */);
638 if (pfile->state.in_expression)
649 /* Non-whitespace disables MI optimization and stops treating
650 '<' as a quote in #include. */
652 if (!pfile->state.in_directive)
653 pfile->mi_valid = false;
655 if (lex_state == ls_none)
658 /* Some of these transitions of state are syntax errors. The
659 ISO preprocessor will issue errors later. */
660 if (lex_state == ls_fun_open)
663 else if (lex_state == ls_hash
664 || lex_state == ls_predicate
665 || lex_state == ls_defined)
668 /* ls_answer and ls_defined_close keep going until ')'. */
673 _cpp_release_buff (pfile, fmacro.buff);
675 if (lex_state == ls_fun_close)
676 cpp_error_with_line (pfile, DL_ERROR, fmacro.line, 0,
677 "unterminated argument list invoking macro \"%s\"",
678 NODE_NAME (fmacro.node));
682 /* Push a context holding the replacement text of the macro NODE on
683 the context stack. NODE is either object-like, or a function-like
684 macro with no arguments. */
686 push_replacement_text (pfile, node)
694 if (node->flags & NODE_BUILTIN)
696 text = _cpp_builtin_macro_text (pfile, node);
697 len = ustrlen (text);
698 buf = _cpp_unaligned_alloc (pfile, len + 1);
699 memcpy (buf, text, len);
705 cpp_macro *macro = node->value.macro;
707 text = macro->exp.text;
711 _cpp_push_text_context (pfile, node, text, len);
714 /* Returns TRUE if traditional macro recursion is detected. */
716 recursive_macro (pfile, node)
720 bool recursing = !!(node->flags & NODE_DISABLED);
722 /* Object-like macros that are already expanding are necessarily
725 However, it is possible to have traditional function-like macros
726 that are not infinitely recursive but recurse to any given depth.
727 Further, it is easy to construct examples that get ever longer
728 until the point they stop recursing. So there is no easy way to
729 detect true recursion; instead we assume any expansion more than
730 20 deep since the first invocation of this macro must be
732 if (recursing && node->value.macro->fun_like)
735 cpp_context *context = pfile->context;
740 if (context->macro == node && depth > 20)
742 context = context->prev;
745 recursing = context != NULL;
749 cpp_error (pfile, DL_ERROR,
750 "detected recursion whilst expanding macro \"%s\"",
756 /* Return the length of the replacement text of a function-like or
757 object-like non-builtin macro. */
759 _cpp_replacement_text_len (macro)
760 const cpp_macro *macro;
769 for (exp = macro->exp.text;;)
771 struct block *b = (struct block *) exp;
774 if (b->arg_index == 0)
776 len += NODE_LEN (macro->params[b->arg_index - 1]);
777 exp += BLOCK_LEN (b->text_len);
786 /* Copy the replacement text of MACRO to DEST, which must be of
787 sufficient size. It is not NUL-terminated. The next character is
790 _cpp_copy_replacement_text (macro, dest)
791 const cpp_macro *macro;
798 for (exp = macro->exp.text;;)
800 struct block *b = (struct block *) exp;
803 memcpy (dest, b->text, b->text_len);
805 if (b->arg_index == 0)
807 param = macro->params[b->arg_index - 1];
808 memcpy (dest, NODE_NAME (param), NODE_LEN (param));
809 dest += NODE_LEN (param);
810 exp += BLOCK_LEN (b->text_len);
815 memcpy (dest, macro->exp.text, macro->count);
816 dest += macro->count;
822 /* Push a context holding the replacement text of the macro NODE on
823 the context stack. NODE is either object-like, or a function-like
824 macro with no arguments. */
826 replace_args_and_push (pfile, fmacro)
828 struct fun_macro *fmacro;
830 cpp_macro *macro = fmacro->node->value.macro;
832 if (macro->paramc == 0)
833 push_replacement_text (pfile, fmacro->node);
841 /* Calculate the length of the argument-replaced text. */
842 for (exp = macro->exp.text;;)
844 struct block *b = (struct block *) exp;
847 if (b->arg_index == 0)
849 len += (fmacro->args[b->arg_index]
850 - fmacro->args[b->arg_index - 1] - 1);
851 exp += BLOCK_LEN (b->text_len);
854 /* Allocate room for the expansion plus \n. */
855 buff = _cpp_get_buff (pfile, len + 1);
857 /* Copy the expansion and replace arguments. */
858 p = BUFF_FRONT (buff);
859 for (exp = macro->exp.text;;)
861 struct block *b = (struct block *) exp;
864 memcpy (p, b->text, b->text_len);
866 if (b->arg_index == 0)
868 arglen = (fmacro->args[b->arg_index]
869 - fmacro->args[b->arg_index - 1] - 1);
870 memcpy (p, pfile->out.base + fmacro->args[b->arg_index - 1],
873 exp += BLOCK_LEN (b->text_len);
878 _cpp_push_text_context (pfile, fmacro->node, BUFF_FRONT (buff), len);
880 /* So we free buffer allocation when macro is left. */
881 pfile->context->buff = buff;
885 /* Read and record the parameters, if any, of a function-like macro
886 definition. Destroys pfile->out.cur.
888 Returns true on success, false on failure (syntax error or a
889 duplicate parameter). On success, CUR (pfile->context) is just
890 past the closing parenthesis. */
892 scan_parameters (pfile, macro)
896 const uchar *cur = CUR (pfile->context) + 1;
901 cur = skip_whitespace (pfile, cur, true /* skip_comments */);
903 if (is_idstart (*cur))
906 if (_cpp_save_parameter (pfile, macro, lex_identifier (pfile, cur)))
908 cur = skip_whitespace (pfile, CUR (pfile->context),
909 true /* skip_comments */);
919 ok = (*cur == ')' && macro->paramc == 0);
923 CUR (pfile->context) = cur + (*cur == ')');
928 /* Save the text from pfile->out.base to pfile->out.cur as
929 the replacement text for the current macro, followed by argument
930 ARG_INDEX, with zero indicating the end of the replacement
933 save_replacement_text (pfile, macro, arg_index)
936 unsigned int arg_index;
938 size_t len = pfile->out.cur - pfile->out.base;
941 if (macro->paramc == 0)
943 /* Object-like and function-like macros without parameters
944 simply store their \n-terminated replacement text. */
945 exp = _cpp_unaligned_alloc (pfile, len + 1);
946 memcpy (exp, pfile->out.base, len);
948 macro->exp.text = exp;
953 /* Store the text's length (unsigned int), the argument index
954 (unsigned short, base 1) and then the text. */
955 size_t blen = BLOCK_LEN (len);
958 if (macro->count + blen > BUFF_ROOM (pfile->a_buff))
959 _cpp_extend_buff (pfile, &pfile->a_buff, macro->count + blen);
961 exp = BUFF_FRONT (pfile->a_buff);
962 block = (struct block *) (exp + macro->count);
963 macro->exp.text = exp;
965 /* Write out the block information. */
966 block->text_len = len;
967 block->arg_index = arg_index;
968 memcpy (block->text, pfile->out.base, len);
970 /* Lex the rest into the start of the output buffer. */
971 pfile->out.cur = pfile->out.base;
973 macro->count += blen;
975 /* If we've finished, commit the memory. */
977 BUFF_FRONT (pfile->a_buff) += macro->count;
981 /* Analyze and save the replacement text of a macro. Returns true on
984 _cpp_create_trad_definition (pfile, macro)
990 cpp_context *context = pfile->context;
992 /* The context has not been set up for command line defines, and CUR
993 has not been updated for the macro name for in-file defines. */
994 pfile->out.cur = pfile->out.base;
995 CUR (context) = pfile->buffer->cur;
996 RLIMIT (context) = pfile->buffer->rlimit;
997 check_output_buffer (pfile, RLIMIT (context) - CUR (context));
999 /* Is this a function-like macro? */
1000 if (* CUR (context) == '(')
1002 /* Setting macro to NULL indicates an error occurred, and
1003 prevents unnecessary work in scan_out_logical_line. */
1004 if (!scan_parameters (pfile, macro))
1008 /* Success. Commit the parameter array. */
1009 macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
1010 BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc];
1011 macro->fun_like = 1;
1015 /* Skip leading whitespace in the replacement text. */
1017 = skip_whitespace (pfile, CUR (context),
1018 CPP_OPTION (pfile, discard_comments_in_macro_exp));
1020 pfile->state.prevent_expansion++;
1021 scan_out_logical_line (pfile, macro);
1022 pfile->state.prevent_expansion--;
1027 /* Skip trailing white space. */
1028 cur = pfile->out.base;
1029 limit = pfile->out.cur;
1030 while (limit > cur && is_space (limit[-1]))
1032 pfile->out.cur = limit;
1033 save_replacement_text (pfile, macro, 0);
1038 /* Copy SRC of length LEN to DEST, but convert all contiguous
1039 whitespace to a single space, provided it is not in quotes. The
1040 quote currently in effect is pointed to by PQUOTE, and is updated
1041 by the function. Returns the number of bytes copied. */
1043 canonicalize_text (dest, src, len, pquote)
1049 uchar *orig_dest = dest;
1050 uchar quote = *pquote;
1054 if (is_space (*src) && !quote)
1058 while (len && is_space (*src));
1063 if (*src == '\'' || *src == '"')
1067 else if (quote == *src)
1070 *dest++ = *src++, len--;
1075 return dest - orig_dest;
1078 /* Returns true if MACRO1 and MACRO2 have expansions different other
1079 than in the form of their whitespace. */
1081 _cpp_expansions_different_trad (macro1, macro2)
1082 const cpp_macro *macro1, *macro2;
1084 uchar *p1 = xmalloc (macro1->count + macro2->count);
1085 uchar *p2 = p1 + macro1->count;
1086 uchar quote1 = 0, quote2 = 0;
1090 if (macro1->paramc > 0)
1092 const uchar *exp1 = macro1->exp.text, *exp2 = macro2->exp.text;
1097 struct block *b1 = (struct block *) exp1;
1098 struct block *b2 = (struct block *) exp2;
1100 if (b1->arg_index != b2->arg_index)
1103 len1 = canonicalize_text (p1, b1->text, b1->text_len, "e1);
1104 len2 = canonicalize_text (p2, b2->text, b2->text_len, "e2);
1105 if (len1 != len2 || memcmp (p1, p2, len1))
1107 if (b1->arg_index == 0)
1112 exp1 += BLOCK_LEN (b1->text_len);
1113 exp2 += BLOCK_LEN (b2->text_len);
1118 len1 = canonicalize_text (p1, macro1->exp.text, macro1->count, "e1);
1119 len2 = canonicalize_text (p2, macro2->exp.text, macro2->count, "e2);
1120 mismatch = (len1 != len2 || memcmp (p1, p2, len1));