xref: /dflybsd-src/contrib/gcc-4.7/libcpp/traditional.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* CPP Library - traditional lexical analysis and macro expansion.
2*e4b17023SJohn Marino    Copyright (C) 2002, 2004, 2005, 2007, 2008, 2009
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino    Contributed by Neil Booth, May 2002
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino This program is free software; you can redistribute it and/or modify it
7*e4b17023SJohn Marino under the terms of the GNU General Public License as published by the
8*e4b17023SJohn Marino Free Software Foundation; either version 3, or (at your option) any
9*e4b17023SJohn Marino later version.
10*e4b17023SJohn Marino 
11*e4b17023SJohn Marino This program is distributed in the hope that it will be useful,
12*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
13*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*e4b17023SJohn Marino GNU General Public License for more details.
15*e4b17023SJohn Marino 
16*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
17*e4b17023SJohn Marino along with this program; see the file COPYING3.  If not see
18*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
19*e4b17023SJohn Marino 
20*e4b17023SJohn Marino #include "config.h"
21*e4b17023SJohn Marino #include "system.h"
22*e4b17023SJohn Marino #include "cpplib.h"
23*e4b17023SJohn Marino #include "internal.h"
24*e4b17023SJohn Marino 
25*e4b17023SJohn Marino /* The replacement text of a function-like macro is stored as a
26*e4b17023SJohn Marino    contiguous sequence of aligned blocks, each representing the text
27*e4b17023SJohn Marino    between subsequent parameters.
28*e4b17023SJohn Marino 
29*e4b17023SJohn Marino    Each block comprises the text between its surrounding parameters,
30*e4b17023SJohn Marino    the length of that text, and the one-based index of the following
31*e4b17023SJohn Marino    parameter.  The final block in the replacement text is easily
32*e4b17023SJohn Marino    recognizable as it has an argument index of zero.  */
33*e4b17023SJohn Marino 
34*e4b17023SJohn Marino struct block
35*e4b17023SJohn Marino {
36*e4b17023SJohn Marino   unsigned int text_len;
37*e4b17023SJohn Marino   unsigned short arg_index;
38*e4b17023SJohn Marino   uchar text[1];
39*e4b17023SJohn Marino };
40*e4b17023SJohn Marino 
41*e4b17023SJohn Marino #define BLOCK_HEADER_LEN offsetof (struct block, text)
42*e4b17023SJohn Marino #define BLOCK_LEN(TEXT_LEN) CPP_ALIGN (BLOCK_HEADER_LEN + (TEXT_LEN))
43*e4b17023SJohn Marino 
44*e4b17023SJohn Marino /* Structure holding information about a function-like macro
45*e4b17023SJohn Marino    invocation.  */
46*e4b17023SJohn Marino struct fun_macro
47*e4b17023SJohn Marino {
48*e4b17023SJohn Marino   /* Memory buffer holding the trad_arg array.  */
49*e4b17023SJohn Marino   _cpp_buff *buff;
50*e4b17023SJohn Marino 
51*e4b17023SJohn Marino   /* An array of size the number of macro parameters + 1, containing
52*e4b17023SJohn Marino      the offsets of the start of each macro argument in the output
53*e4b17023SJohn Marino      buffer.  The argument continues until the character before the
54*e4b17023SJohn Marino      start of the next one.  */
55*e4b17023SJohn Marino   size_t *args;
56*e4b17023SJohn Marino 
57*e4b17023SJohn Marino   /* The hashnode of the macro.  */
58*e4b17023SJohn Marino   cpp_hashnode *node;
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino   /* The offset of the macro name in the output buffer.  */
61*e4b17023SJohn Marino   size_t offset;
62*e4b17023SJohn Marino 
63*e4b17023SJohn Marino   /* The line the macro name appeared on.  */
64*e4b17023SJohn Marino   source_location line;
65*e4b17023SJohn Marino 
66*e4b17023SJohn Marino   /* Zero-based index of argument being currently lexed.  */
67*e4b17023SJohn Marino   unsigned int argc;
68*e4b17023SJohn Marino };
69*e4b17023SJohn Marino 
70*e4b17023SJohn Marino /* Lexing state.  It is mostly used to prevent macro expansion.  */
71*e4b17023SJohn Marino enum ls {ls_none = 0,		/* Normal state.  */
72*e4b17023SJohn Marino 	 ls_fun_open,		/* When looking for '('.  */
73*e4b17023SJohn Marino 	 ls_fun_close,		/* When looking for ')'.  */
74*e4b17023SJohn Marino 	 ls_defined,		/* After defined.  */
75*e4b17023SJohn Marino 	 ls_defined_close,	/* Looking for ')' of defined().  */
76*e4b17023SJohn Marino 	 ls_hash,		/* After # in preprocessor conditional.  */
77*e4b17023SJohn Marino 	 ls_predicate,		/* After the predicate, maybe paren?  */
78*e4b17023SJohn Marino 	 ls_answer};		/* In answer to predicate.  */
79*e4b17023SJohn Marino 
80*e4b17023SJohn Marino /* Lexing TODO: Maybe handle space in escaped newlines.  Stop lex.c
81*e4b17023SJohn Marino    from recognizing comments and directives during its lexing pass.  */
82*e4b17023SJohn Marino 
83*e4b17023SJohn Marino static const uchar *skip_whitespace (cpp_reader *, const uchar *, int);
84*e4b17023SJohn Marino static cpp_hashnode *lex_identifier (cpp_reader *, const uchar *);
85*e4b17023SJohn Marino static const uchar *copy_comment (cpp_reader *, const uchar *, int);
86*e4b17023SJohn Marino static void check_output_buffer (cpp_reader *, size_t);
87*e4b17023SJohn Marino static void push_replacement_text (cpp_reader *, cpp_hashnode *);
88*e4b17023SJohn Marino static bool scan_parameters (cpp_reader *, cpp_macro *);
89*e4b17023SJohn Marino static bool recursive_macro (cpp_reader *, cpp_hashnode *);
90*e4b17023SJohn Marino static void save_replacement_text (cpp_reader *, cpp_macro *, unsigned int);
91*e4b17023SJohn Marino static void maybe_start_funlike (cpp_reader *, cpp_hashnode *, const uchar *,
92*e4b17023SJohn Marino 				 struct fun_macro *);
93*e4b17023SJohn Marino static void save_argument (struct fun_macro *, size_t);
94*e4b17023SJohn Marino static void replace_args_and_push (cpp_reader *, struct fun_macro *);
95*e4b17023SJohn Marino static size_t canonicalize_text (uchar *, const uchar *, size_t, uchar *);
96*e4b17023SJohn Marino 
97*e4b17023SJohn Marino /* Ensures we have N bytes' space in the output buffer, and
98*e4b17023SJohn Marino    reallocates it if not.  */
99*e4b17023SJohn Marino static void
check_output_buffer(cpp_reader * pfile,size_t n)100*e4b17023SJohn Marino check_output_buffer (cpp_reader *pfile, size_t n)
101*e4b17023SJohn Marino {
102*e4b17023SJohn Marino   /* We might need two bytes to terminate an unterminated comment, and
103*e4b17023SJohn Marino      one more to terminate the line with a NUL.  */
104*e4b17023SJohn Marino   n += 2 + 1;
105*e4b17023SJohn Marino 
106*e4b17023SJohn Marino   if (n > (size_t) (pfile->out.limit - pfile->out.cur))
107*e4b17023SJohn Marino     {
108*e4b17023SJohn Marino       size_t size = pfile->out.cur - pfile->out.base;
109*e4b17023SJohn Marino       size_t new_size = (size + n) * 3 / 2;
110*e4b17023SJohn Marino 
111*e4b17023SJohn Marino       pfile->out.base = XRESIZEVEC (unsigned char, pfile->out.base, new_size);
112*e4b17023SJohn Marino       pfile->out.limit = pfile->out.base + new_size;
113*e4b17023SJohn Marino       pfile->out.cur = pfile->out.base + size;
114*e4b17023SJohn Marino     }
115*e4b17023SJohn Marino }
116*e4b17023SJohn Marino 
117*e4b17023SJohn Marino /* Skip a C-style block comment in a macro as a result of -CC.
118*e4b17023SJohn Marino    Buffer->cur points to the initial asterisk of the comment.  */
119*e4b17023SJohn Marino static void
skip_macro_block_comment(cpp_reader * pfile)120*e4b17023SJohn Marino skip_macro_block_comment (cpp_reader *pfile)
121*e4b17023SJohn Marino {
122*e4b17023SJohn Marino   const uchar *cur = pfile->buffer->cur;
123*e4b17023SJohn Marino 
124*e4b17023SJohn Marino   cur++;
125*e4b17023SJohn Marino   if (*cur == '/')
126*e4b17023SJohn Marino     cur++;
127*e4b17023SJohn Marino 
128*e4b17023SJohn Marino   /* People like decorating comments with '*', so check for '/'
129*e4b17023SJohn Marino      instead for efficiency.  */
130*e4b17023SJohn Marino   while(! (*cur++ == '/' && cur[-2] == '*') )
131*e4b17023SJohn Marino     ;
132*e4b17023SJohn Marino 
133*e4b17023SJohn Marino   pfile->buffer->cur = cur;
134*e4b17023SJohn Marino }
135*e4b17023SJohn Marino 
136*e4b17023SJohn Marino /* CUR points to the asterisk introducing a comment in the current
137*e4b17023SJohn Marino    context.  IN_DEFINE is true if we are in the replacement text of a
138*e4b17023SJohn Marino    macro.
139*e4b17023SJohn Marino 
140*e4b17023SJohn Marino    The asterisk and following comment is copied to the buffer pointed
141*e4b17023SJohn Marino    to by pfile->out.cur, which must be of sufficient size.
142*e4b17023SJohn Marino    Unterminated comments are diagnosed, and correctly terminated in
143*e4b17023SJohn Marino    the output.  pfile->out.cur is updated depending upon IN_DEFINE,
144*e4b17023SJohn Marino    -C, -CC and pfile->state.in_directive.
145*e4b17023SJohn Marino 
146*e4b17023SJohn Marino    Returns a pointer to the first character after the comment in the
147*e4b17023SJohn Marino    input buffer.  */
148*e4b17023SJohn Marino static const uchar *
copy_comment(cpp_reader * pfile,const uchar * cur,int in_define)149*e4b17023SJohn Marino copy_comment (cpp_reader *pfile, const uchar *cur, int in_define)
150*e4b17023SJohn Marino {
151*e4b17023SJohn Marino   bool unterminated, copy = false;
152*e4b17023SJohn Marino   source_location src_loc = pfile->line_table->highest_line;
153*e4b17023SJohn Marino   cpp_buffer *buffer = pfile->buffer;
154*e4b17023SJohn Marino 
155*e4b17023SJohn Marino   buffer->cur = cur;
156*e4b17023SJohn Marino   if (pfile->context->prev)
157*e4b17023SJohn Marino     unterminated = false, skip_macro_block_comment (pfile);
158*e4b17023SJohn Marino   else
159*e4b17023SJohn Marino     unterminated = _cpp_skip_block_comment (pfile);
160*e4b17023SJohn Marino 
161*e4b17023SJohn Marino   if (unterminated)
162*e4b17023SJohn Marino     cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0,
163*e4b17023SJohn Marino 			 "unterminated comment");
164*e4b17023SJohn Marino 
165*e4b17023SJohn Marino   /* Comments in directives become spaces so that tokens are properly
166*e4b17023SJohn Marino      separated when the ISO preprocessor re-lexes the line.  The
167*e4b17023SJohn Marino      exception is #define.  */
168*e4b17023SJohn Marino   if (pfile->state.in_directive)
169*e4b17023SJohn Marino     {
170*e4b17023SJohn Marino       if (in_define)
171*e4b17023SJohn Marino 	{
172*e4b17023SJohn Marino 	  if (CPP_OPTION (pfile, discard_comments_in_macro_exp))
173*e4b17023SJohn Marino 	    pfile->out.cur--;
174*e4b17023SJohn Marino 	  else
175*e4b17023SJohn Marino 	    copy = true;
176*e4b17023SJohn Marino 	}
177*e4b17023SJohn Marino       else
178*e4b17023SJohn Marino 	pfile->out.cur[-1] = ' ';
179*e4b17023SJohn Marino     }
180*e4b17023SJohn Marino   else if (CPP_OPTION (pfile, discard_comments))
181*e4b17023SJohn Marino     pfile->out.cur--;
182*e4b17023SJohn Marino   else
183*e4b17023SJohn Marino     copy = true;
184*e4b17023SJohn Marino 
185*e4b17023SJohn Marino   if (copy)
186*e4b17023SJohn Marino     {
187*e4b17023SJohn Marino       size_t len = (size_t) (buffer->cur - cur);
188*e4b17023SJohn Marino       memcpy (pfile->out.cur, cur, len);
189*e4b17023SJohn Marino       pfile->out.cur += len;
190*e4b17023SJohn Marino       if (unterminated)
191*e4b17023SJohn Marino 	{
192*e4b17023SJohn Marino 	  *pfile->out.cur++ = '*';
193*e4b17023SJohn Marino 	  *pfile->out.cur++ = '/';
194*e4b17023SJohn Marino 	}
195*e4b17023SJohn Marino     }
196*e4b17023SJohn Marino 
197*e4b17023SJohn Marino   return buffer->cur;
198*e4b17023SJohn Marino }
199*e4b17023SJohn Marino 
200*e4b17023SJohn Marino /* CUR points to any character in the input buffer.  Skips over all
201*e4b17023SJohn Marino    contiguous horizontal white space and NULs, including comments if
202*e4b17023SJohn Marino    SKIP_COMMENTS, until reaching the first non-horizontal-whitespace
203*e4b17023SJohn Marino    character or the end of the current context.  Escaped newlines are
204*e4b17023SJohn Marino    removed.
205*e4b17023SJohn Marino 
206*e4b17023SJohn Marino    The whitespace is copied verbatim to the output buffer, except that
207*e4b17023SJohn Marino    comments are handled as described in copy_comment().
208*e4b17023SJohn Marino    pfile->out.cur is updated.
209*e4b17023SJohn Marino 
210*e4b17023SJohn Marino    Returns a pointer to the first character after the whitespace in
211*e4b17023SJohn Marino    the input buffer.  */
212*e4b17023SJohn Marino static const uchar *
skip_whitespace(cpp_reader * pfile,const uchar * cur,int skip_comments)213*e4b17023SJohn Marino skip_whitespace (cpp_reader *pfile, const uchar *cur, int skip_comments)
214*e4b17023SJohn Marino {
215*e4b17023SJohn Marino   uchar *out = pfile->out.cur;
216*e4b17023SJohn Marino 
217*e4b17023SJohn Marino   for (;;)
218*e4b17023SJohn Marino     {
219*e4b17023SJohn Marino       unsigned int c = *cur++;
220*e4b17023SJohn Marino       *out++ = c;
221*e4b17023SJohn Marino 
222*e4b17023SJohn Marino       if (is_nvspace (c))
223*e4b17023SJohn Marino 	continue;
224*e4b17023SJohn Marino 
225*e4b17023SJohn Marino       if (c == '/' && *cur == '*' && skip_comments)
226*e4b17023SJohn Marino 	{
227*e4b17023SJohn Marino 	  pfile->out.cur = out;
228*e4b17023SJohn Marino 	  cur = copy_comment (pfile, cur, false /* in_define */);
229*e4b17023SJohn Marino 	  out = pfile->out.cur;
230*e4b17023SJohn Marino 	  continue;
231*e4b17023SJohn Marino 	}
232*e4b17023SJohn Marino 
233*e4b17023SJohn Marino       out--;
234*e4b17023SJohn Marino       break;
235*e4b17023SJohn Marino     }
236*e4b17023SJohn Marino 
237*e4b17023SJohn Marino   pfile->out.cur = out;
238*e4b17023SJohn Marino   return cur - 1;
239*e4b17023SJohn Marino }
240*e4b17023SJohn Marino 
241*e4b17023SJohn Marino /* Lexes and outputs an identifier starting at CUR, which is assumed
242*e4b17023SJohn Marino    to point to a valid first character of an identifier.  Returns
243*e4b17023SJohn Marino    the hashnode, and updates out.cur.  */
244*e4b17023SJohn Marino static cpp_hashnode *
lex_identifier(cpp_reader * pfile,const uchar * cur)245*e4b17023SJohn Marino lex_identifier (cpp_reader *pfile, const uchar *cur)
246*e4b17023SJohn Marino {
247*e4b17023SJohn Marino   size_t len;
248*e4b17023SJohn Marino   uchar *out = pfile->out.cur;
249*e4b17023SJohn Marino   cpp_hashnode *result;
250*e4b17023SJohn Marino 
251*e4b17023SJohn Marino   do
252*e4b17023SJohn Marino     *out++ = *cur++;
253*e4b17023SJohn Marino   while (is_numchar (*cur));
254*e4b17023SJohn Marino 
255*e4b17023SJohn Marino   CUR (pfile->context) = cur;
256*e4b17023SJohn Marino   len = out - pfile->out.cur;
257*e4b17023SJohn Marino   result = CPP_HASHNODE (ht_lookup (pfile->hash_table, pfile->out.cur,
258*e4b17023SJohn Marino 				    len, HT_ALLOC));
259*e4b17023SJohn Marino   pfile->out.cur = out;
260*e4b17023SJohn Marino   return result;
261*e4b17023SJohn Marino }
262*e4b17023SJohn Marino 
263*e4b17023SJohn Marino /* Overlays the true file buffer temporarily with text of length LEN
264*e4b17023SJohn Marino    starting at START.  The true buffer is restored upon calling
265*e4b17023SJohn Marino    restore_buff().  */
266*e4b17023SJohn Marino void
_cpp_overlay_buffer(cpp_reader * pfile,const uchar * start,size_t len)267*e4b17023SJohn Marino _cpp_overlay_buffer (cpp_reader *pfile, const uchar *start, size_t len)
268*e4b17023SJohn Marino {
269*e4b17023SJohn Marino   cpp_buffer *buffer = pfile->buffer;
270*e4b17023SJohn Marino 
271*e4b17023SJohn Marino   pfile->overlaid_buffer = buffer;
272*e4b17023SJohn Marino   pfile->saved_cur = buffer->cur;
273*e4b17023SJohn Marino   pfile->saved_rlimit = buffer->rlimit;
274*e4b17023SJohn Marino   pfile->saved_line_base = buffer->next_line;
275*e4b17023SJohn Marino   buffer->need_line = false;
276*e4b17023SJohn Marino 
277*e4b17023SJohn Marino   buffer->cur = start;
278*e4b17023SJohn Marino   buffer->line_base = start;
279*e4b17023SJohn Marino   buffer->rlimit = start + len;
280*e4b17023SJohn Marino }
281*e4b17023SJohn Marino 
282*e4b17023SJohn Marino /* Restores a buffer overlaid by _cpp_overlay_buffer().  */
283*e4b17023SJohn Marino void
_cpp_remove_overlay(cpp_reader * pfile)284*e4b17023SJohn Marino _cpp_remove_overlay (cpp_reader *pfile)
285*e4b17023SJohn Marino {
286*e4b17023SJohn Marino   cpp_buffer *buffer = pfile->overlaid_buffer;
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino   buffer->cur = pfile->saved_cur;
289*e4b17023SJohn Marino   buffer->rlimit = pfile->saved_rlimit;
290*e4b17023SJohn Marino   buffer->line_base = pfile->saved_line_base;
291*e4b17023SJohn Marino   buffer->need_line = true;
292*e4b17023SJohn Marino 
293*e4b17023SJohn Marino   pfile->overlaid_buffer = NULL;
294*e4b17023SJohn Marino }
295*e4b17023SJohn Marino 
296*e4b17023SJohn Marino /* Reads a logical line into the output buffer.  Returns TRUE if there
297*e4b17023SJohn Marino    is more text left in the buffer.  */
298*e4b17023SJohn Marino bool
_cpp_read_logical_line_trad(cpp_reader * pfile)299*e4b17023SJohn Marino _cpp_read_logical_line_trad (cpp_reader *pfile)
300*e4b17023SJohn Marino {
301*e4b17023SJohn Marino   do
302*e4b17023SJohn Marino     {
303*e4b17023SJohn Marino       if (pfile->buffer->need_line && !_cpp_get_fresh_line (pfile))
304*e4b17023SJohn Marino 	return false;
305*e4b17023SJohn Marino     }
306*e4b17023SJohn Marino   while (!_cpp_scan_out_logical_line (pfile, NULL) || pfile->state.skipping);
307*e4b17023SJohn Marino 
308*e4b17023SJohn Marino   return pfile->buffer != NULL;
309*e4b17023SJohn Marino }
310*e4b17023SJohn Marino 
311*e4b17023SJohn Marino /* Set up state for finding the opening '(' of a function-like
312*e4b17023SJohn Marino    macro.  */
313*e4b17023SJohn Marino static void
maybe_start_funlike(cpp_reader * pfile,cpp_hashnode * node,const uchar * start,struct fun_macro * macro)314*e4b17023SJohn Marino maybe_start_funlike (cpp_reader *pfile, cpp_hashnode *node, const uchar *start, struct fun_macro *macro)
315*e4b17023SJohn Marino {
316*e4b17023SJohn Marino   unsigned int n = node->value.macro->paramc + 1;
317*e4b17023SJohn Marino 
318*e4b17023SJohn Marino   if (macro->buff)
319*e4b17023SJohn Marino     _cpp_release_buff (pfile, macro->buff);
320*e4b17023SJohn Marino   macro->buff = _cpp_get_buff (pfile, n * sizeof (size_t));
321*e4b17023SJohn Marino   macro->args = (size_t *) BUFF_FRONT (macro->buff);
322*e4b17023SJohn Marino   macro->node = node;
323*e4b17023SJohn Marino   macro->offset = start - pfile->out.base;
324*e4b17023SJohn Marino   macro->argc = 0;
325*e4b17023SJohn Marino }
326*e4b17023SJohn Marino 
327*e4b17023SJohn Marino /* Save the OFFSET of the start of the next argument to MACRO.  */
328*e4b17023SJohn Marino static void
save_argument(struct fun_macro * macro,size_t offset)329*e4b17023SJohn Marino save_argument (struct fun_macro *macro, size_t offset)
330*e4b17023SJohn Marino {
331*e4b17023SJohn Marino   macro->argc++;
332*e4b17023SJohn Marino   if (macro->argc <= macro->node->value.macro->paramc)
333*e4b17023SJohn Marino     macro->args[macro->argc] = offset;
334*e4b17023SJohn Marino }
335*e4b17023SJohn Marino 
336*e4b17023SJohn Marino /* Copies the next logical line in the current buffer (starting at
337*e4b17023SJohn Marino    buffer->cur) to the output buffer.  The output is guaranteed to
338*e4b17023SJohn Marino    terminate with a NUL character.  buffer->cur is updated.
339*e4b17023SJohn Marino 
340*e4b17023SJohn Marino    If MACRO is non-NULL, then we are scanning the replacement list of
341*e4b17023SJohn Marino    MACRO, and we call save_replacement_text() every time we meet an
342*e4b17023SJohn Marino    argument.  */
343*e4b17023SJohn Marino bool
_cpp_scan_out_logical_line(cpp_reader * pfile,cpp_macro * macro)344*e4b17023SJohn Marino _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro)
345*e4b17023SJohn Marino {
346*e4b17023SJohn Marino   bool result = true;
347*e4b17023SJohn Marino   cpp_context *context;
348*e4b17023SJohn Marino   const uchar *cur;
349*e4b17023SJohn Marino   uchar *out;
350*e4b17023SJohn Marino   struct fun_macro fmacro;
351*e4b17023SJohn Marino   unsigned int c, paren_depth = 0, quote;
352*e4b17023SJohn Marino   enum ls lex_state = ls_none;
353*e4b17023SJohn Marino   bool header_ok;
354*e4b17023SJohn Marino   const uchar *start_of_input_line;
355*e4b17023SJohn Marino 
356*e4b17023SJohn Marino   fmacro.buff = NULL;
357*e4b17023SJohn Marino   fmacro.args = NULL;
358*e4b17023SJohn Marino   fmacro.node = NULL;
359*e4b17023SJohn Marino   fmacro.offset = 0;
360*e4b17023SJohn Marino   fmacro.line = 0;
361*e4b17023SJohn Marino   fmacro.argc = 0;
362*e4b17023SJohn Marino 
363*e4b17023SJohn Marino   quote = 0;
364*e4b17023SJohn Marino   header_ok = pfile->state.angled_headers;
365*e4b17023SJohn Marino   CUR (pfile->context) = pfile->buffer->cur;
366*e4b17023SJohn Marino   RLIMIT (pfile->context) = pfile->buffer->rlimit;
367*e4b17023SJohn Marino   pfile->out.cur = pfile->out.base;
368*e4b17023SJohn Marino   pfile->out.first_line = pfile->line_table->highest_line;
369*e4b17023SJohn Marino   /* start_of_input_line is needed to make sure that directives really,
370*e4b17023SJohn Marino      really start at the first character of the line.  */
371*e4b17023SJohn Marino   start_of_input_line = pfile->buffer->cur;
372*e4b17023SJohn Marino  new_context:
373*e4b17023SJohn Marino   context = pfile->context;
374*e4b17023SJohn Marino   cur = CUR (context);
375*e4b17023SJohn Marino   check_output_buffer (pfile, RLIMIT (context) - cur);
376*e4b17023SJohn Marino   out = pfile->out.cur;
377*e4b17023SJohn Marino 
378*e4b17023SJohn Marino   for (;;)
379*e4b17023SJohn Marino     {
380*e4b17023SJohn Marino       if (!context->prev
381*e4b17023SJohn Marino 	  && cur >= pfile->buffer->notes[pfile->buffer->cur_note].pos)
382*e4b17023SJohn Marino 	{
383*e4b17023SJohn Marino 	  pfile->buffer->cur = cur;
384*e4b17023SJohn Marino 	  _cpp_process_line_notes (pfile, false);
385*e4b17023SJohn Marino 	}
386*e4b17023SJohn Marino       c = *cur++;
387*e4b17023SJohn Marino       *out++ = c;
388*e4b17023SJohn Marino 
389*e4b17023SJohn Marino       /* Whitespace should "continue" out of the switch,
390*e4b17023SJohn Marino 	 non-whitespace should "break" out of it.  */
391*e4b17023SJohn Marino       switch (c)
392*e4b17023SJohn Marino 	{
393*e4b17023SJohn Marino 	case ' ':
394*e4b17023SJohn Marino 	case '\t':
395*e4b17023SJohn Marino 	case '\f':
396*e4b17023SJohn Marino 	case '\v':
397*e4b17023SJohn Marino 	case '\0':
398*e4b17023SJohn Marino 	  continue;
399*e4b17023SJohn Marino 
400*e4b17023SJohn Marino 	case '\n':
401*e4b17023SJohn Marino 	  /* If this is a macro's expansion, pop it.  */
402*e4b17023SJohn Marino 	  if (context->prev)
403*e4b17023SJohn Marino 	    {
404*e4b17023SJohn Marino 	      pfile->out.cur = out - 1;
405*e4b17023SJohn Marino 	      _cpp_pop_context (pfile);
406*e4b17023SJohn Marino 	      goto new_context;
407*e4b17023SJohn Marino 	    }
408*e4b17023SJohn Marino 
409*e4b17023SJohn Marino 	  /* Omit the newline from the output buffer.  */
410*e4b17023SJohn Marino 	  pfile->out.cur = out - 1;
411*e4b17023SJohn Marino 	  pfile->buffer->cur = cur;
412*e4b17023SJohn Marino 	  pfile->buffer->need_line = true;
413*e4b17023SJohn Marino 	  CPP_INCREMENT_LINE (pfile, 0);
414*e4b17023SJohn Marino 
415*e4b17023SJohn Marino 	  if ((lex_state == ls_fun_open || lex_state == ls_fun_close)
416*e4b17023SJohn Marino 	      && !pfile->state.in_directive
417*e4b17023SJohn Marino 	      && _cpp_get_fresh_line (pfile))
418*e4b17023SJohn Marino 	    {
419*e4b17023SJohn Marino 	      /* Newlines in arguments become a space, but we don't
420*e4b17023SJohn Marino 		 clear any in-progress quote.  */
421*e4b17023SJohn Marino 	      if (lex_state == ls_fun_close)
422*e4b17023SJohn Marino 		out[-1] = ' ';
423*e4b17023SJohn Marino 	      cur = pfile->buffer->cur;
424*e4b17023SJohn Marino 	      continue;
425*e4b17023SJohn Marino 	    }
426*e4b17023SJohn Marino 	  goto done;
427*e4b17023SJohn Marino 
428*e4b17023SJohn Marino 	case '<':
429*e4b17023SJohn Marino 	  if (header_ok)
430*e4b17023SJohn Marino 	    quote = '>';
431*e4b17023SJohn Marino 	  break;
432*e4b17023SJohn Marino 	case '>':
433*e4b17023SJohn Marino 	  if (c == quote)
434*e4b17023SJohn Marino 	    quote = 0;
435*e4b17023SJohn Marino 	  break;
436*e4b17023SJohn Marino 
437*e4b17023SJohn Marino 	case '"':
438*e4b17023SJohn Marino 	case '\'':
439*e4b17023SJohn Marino 	  if (c == quote)
440*e4b17023SJohn Marino 	    quote = 0;
441*e4b17023SJohn Marino 	  else if (!quote)
442*e4b17023SJohn Marino 	    quote = c;
443*e4b17023SJohn Marino 	  break;
444*e4b17023SJohn Marino 
445*e4b17023SJohn Marino 	case '\\':
446*e4b17023SJohn Marino 	  /* Skip escaped quotes here, it's easier than above.  */
447*e4b17023SJohn Marino 	  if (*cur == '\\' || *cur == '"' || *cur == '\'')
448*e4b17023SJohn Marino 	    *out++ = *cur++;
449*e4b17023SJohn Marino 	  break;
450*e4b17023SJohn Marino 
451*e4b17023SJohn Marino 	case '/':
452*e4b17023SJohn Marino 	  /* Traditional CPP does not recognize comments within
453*e4b17023SJohn Marino 	     literals.  */
454*e4b17023SJohn Marino 	  if (!quote && *cur == '*')
455*e4b17023SJohn Marino 	    {
456*e4b17023SJohn Marino 	      pfile->out.cur = out;
457*e4b17023SJohn Marino 	      cur = copy_comment (pfile, cur, macro != 0);
458*e4b17023SJohn Marino 	      out = pfile->out.cur;
459*e4b17023SJohn Marino 	      continue;
460*e4b17023SJohn Marino 	    }
461*e4b17023SJohn Marino 	  break;
462*e4b17023SJohn Marino 
463*e4b17023SJohn Marino 	case '_':
464*e4b17023SJohn Marino 	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
465*e4b17023SJohn Marino 	case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
466*e4b17023SJohn Marino 	case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
467*e4b17023SJohn Marino 	case 's': case 't': case 'u': case 'v': case 'w': case 'x':
468*e4b17023SJohn Marino 	case 'y': case 'z':
469*e4b17023SJohn Marino 	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
470*e4b17023SJohn Marino 	case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
471*e4b17023SJohn Marino 	case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
472*e4b17023SJohn Marino 	case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
473*e4b17023SJohn Marino 	case 'Y': case 'Z':
474*e4b17023SJohn Marino 	  if (!pfile->state.skipping && (quote == 0 || macro))
475*e4b17023SJohn Marino 	    {
476*e4b17023SJohn Marino 	      cpp_hashnode *node;
477*e4b17023SJohn Marino 	      uchar *out_start = out - 1;
478*e4b17023SJohn Marino 
479*e4b17023SJohn Marino 	      pfile->out.cur = out_start;
480*e4b17023SJohn Marino 	      node = lex_identifier (pfile, cur - 1);
481*e4b17023SJohn Marino 	      out = pfile->out.cur;
482*e4b17023SJohn Marino 	      cur = CUR (context);
483*e4b17023SJohn Marino 
484*e4b17023SJohn Marino 	      if (node->type == NT_MACRO
485*e4b17023SJohn Marino 		  /* Should we expand for ls_answer?  */
486*e4b17023SJohn Marino 		  && (lex_state == ls_none || lex_state == ls_fun_open)
487*e4b17023SJohn Marino 		  && !pfile->state.prevent_expansion)
488*e4b17023SJohn Marino 		{
489*e4b17023SJohn Marino 		  /* Macros invalidate MI optimization.  */
490*e4b17023SJohn Marino 		  pfile->mi_valid = false;
491*e4b17023SJohn Marino 		  if (! (node->flags & NODE_BUILTIN)
492*e4b17023SJohn Marino 		      && node->value.macro->fun_like)
493*e4b17023SJohn Marino 		    {
494*e4b17023SJohn Marino 		      maybe_start_funlike (pfile, node, out_start, &fmacro);
495*e4b17023SJohn Marino 		      lex_state = ls_fun_open;
496*e4b17023SJohn Marino 		      fmacro.line = pfile->line_table->highest_line;
497*e4b17023SJohn Marino 		      continue;
498*e4b17023SJohn Marino 		    }
499*e4b17023SJohn Marino 		  else if (!recursive_macro (pfile, node))
500*e4b17023SJohn Marino 		    {
501*e4b17023SJohn Marino 		      /* Remove the object-like macro's name from the
502*e4b17023SJohn Marino 			 output, and push its replacement text.  */
503*e4b17023SJohn Marino 		      pfile->out.cur = out_start;
504*e4b17023SJohn Marino 		      push_replacement_text (pfile, node);
505*e4b17023SJohn Marino 		      lex_state = ls_none;
506*e4b17023SJohn Marino 		      goto new_context;
507*e4b17023SJohn Marino 		    }
508*e4b17023SJohn Marino 		}
509*e4b17023SJohn Marino 	      else if (macro && (node->flags & NODE_MACRO_ARG) != 0)
510*e4b17023SJohn Marino 		{
511*e4b17023SJohn Marino 		  /* Found a parameter in the replacement text of a
512*e4b17023SJohn Marino 		     #define.  Remove its name from the output.  */
513*e4b17023SJohn Marino 		  pfile->out.cur = out_start;
514*e4b17023SJohn Marino 		  save_replacement_text (pfile, macro, node->value.arg_index);
515*e4b17023SJohn Marino 		  out = pfile->out.base;
516*e4b17023SJohn Marino 		}
517*e4b17023SJohn Marino 	      else if (lex_state == ls_hash)
518*e4b17023SJohn Marino 		{
519*e4b17023SJohn Marino 		  lex_state = ls_predicate;
520*e4b17023SJohn Marino 		  continue;
521*e4b17023SJohn Marino 		}
522*e4b17023SJohn Marino 	      else if (pfile->state.in_expression
523*e4b17023SJohn Marino 		       && node == pfile->spec_nodes.n_defined)
524*e4b17023SJohn Marino 		{
525*e4b17023SJohn Marino 		  lex_state = ls_defined;
526*e4b17023SJohn Marino 		  continue;
527*e4b17023SJohn Marino 		}
528*e4b17023SJohn Marino 	    }
529*e4b17023SJohn Marino 	  break;
530*e4b17023SJohn Marino 
531*e4b17023SJohn Marino 	case '(':
532*e4b17023SJohn Marino 	  if (quote == 0)
533*e4b17023SJohn Marino 	    {
534*e4b17023SJohn Marino 	      paren_depth++;
535*e4b17023SJohn Marino 	      if (lex_state == ls_fun_open)
536*e4b17023SJohn Marino 		{
537*e4b17023SJohn Marino 		  if (recursive_macro (pfile, fmacro.node))
538*e4b17023SJohn Marino 		    lex_state = ls_none;
539*e4b17023SJohn Marino 		  else
540*e4b17023SJohn Marino 		    {
541*e4b17023SJohn Marino 		      lex_state = ls_fun_close;
542*e4b17023SJohn Marino 		      paren_depth = 1;
543*e4b17023SJohn Marino 		      out = pfile->out.base + fmacro.offset;
544*e4b17023SJohn Marino 		      fmacro.args[0] = fmacro.offset;
545*e4b17023SJohn Marino 		    }
546*e4b17023SJohn Marino 		}
547*e4b17023SJohn Marino 	      else if (lex_state == ls_predicate)
548*e4b17023SJohn Marino 		lex_state = ls_answer;
549*e4b17023SJohn Marino 	      else if (lex_state == ls_defined)
550*e4b17023SJohn Marino 		lex_state = ls_defined_close;
551*e4b17023SJohn Marino 	    }
552*e4b17023SJohn Marino 	  break;
553*e4b17023SJohn Marino 
554*e4b17023SJohn Marino 	case ',':
555*e4b17023SJohn Marino 	  if (quote == 0 && lex_state == ls_fun_close && paren_depth == 1)
556*e4b17023SJohn Marino 	    save_argument (&fmacro, out - pfile->out.base);
557*e4b17023SJohn Marino 	  break;
558*e4b17023SJohn Marino 
559*e4b17023SJohn Marino 	case ')':
560*e4b17023SJohn Marino 	  if (quote == 0)
561*e4b17023SJohn Marino 	    {
562*e4b17023SJohn Marino 	      paren_depth--;
563*e4b17023SJohn Marino 	      if (lex_state == ls_fun_close && paren_depth == 0)
564*e4b17023SJohn Marino 		{
565*e4b17023SJohn Marino 		  cpp_macro *m = fmacro.node->value.macro;
566*e4b17023SJohn Marino 
567*e4b17023SJohn Marino 		  m->used = 1;
568*e4b17023SJohn Marino 		  lex_state = ls_none;
569*e4b17023SJohn Marino 		  save_argument (&fmacro, out - pfile->out.base);
570*e4b17023SJohn Marino 
571*e4b17023SJohn Marino 		  /* A single zero-length argument is no argument.  */
572*e4b17023SJohn Marino 		  if (fmacro.argc == 1
573*e4b17023SJohn Marino 		      && m->paramc == 0
574*e4b17023SJohn Marino 		      && out == pfile->out.base + fmacro.offset + 1)
575*e4b17023SJohn Marino 		    fmacro.argc = 0;
576*e4b17023SJohn Marino 
577*e4b17023SJohn Marino 		  if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc))
578*e4b17023SJohn Marino 		    {
579*e4b17023SJohn Marino 		      /* Remove the macro's invocation from the
580*e4b17023SJohn Marino 			 output, and push its replacement text.  */
581*e4b17023SJohn Marino 		      pfile->out.cur = (pfile->out.base
582*e4b17023SJohn Marino 					     + fmacro.offset);
583*e4b17023SJohn Marino 		      CUR (context) = cur;
584*e4b17023SJohn Marino 		      replace_args_and_push (pfile, &fmacro);
585*e4b17023SJohn Marino 		      goto new_context;
586*e4b17023SJohn Marino 		    }
587*e4b17023SJohn Marino 		}
588*e4b17023SJohn Marino 	      else if (lex_state == ls_answer || lex_state == ls_defined_close)
589*e4b17023SJohn Marino 		lex_state = ls_none;
590*e4b17023SJohn Marino 	    }
591*e4b17023SJohn Marino 	  break;
592*e4b17023SJohn Marino 
593*e4b17023SJohn Marino 	case '#':
594*e4b17023SJohn Marino 	  if (cur - 1 == start_of_input_line
595*e4b17023SJohn Marino 	      /* A '#' from a macro doesn't start a directive.  */
596*e4b17023SJohn Marino 	      && !pfile->context->prev
597*e4b17023SJohn Marino 	      && !pfile->state.in_directive)
598*e4b17023SJohn Marino 	    {
599*e4b17023SJohn Marino 	      /* A directive.  With the way _cpp_handle_directive
600*e4b17023SJohn Marino 		 currently works, we only want to call it if either we
601*e4b17023SJohn Marino 		 know the directive is OK, or we want it to fail and
602*e4b17023SJohn Marino 		 be removed from the output.  If we want it to be
603*e4b17023SJohn Marino 		 passed through (the assembler case) then we must not
604*e4b17023SJohn Marino 		 call _cpp_handle_directive.  */
605*e4b17023SJohn Marino 	      pfile->out.cur = out;
606*e4b17023SJohn Marino 	      cur = skip_whitespace (pfile, cur, true /* skip_comments */);
607*e4b17023SJohn Marino 	      out = pfile->out.cur;
608*e4b17023SJohn Marino 
609*e4b17023SJohn Marino 	      if (*cur == '\n')
610*e4b17023SJohn Marino 		{
611*e4b17023SJohn Marino 		  /* Null directive.  Ignore it and don't invalidate
612*e4b17023SJohn Marino 		     the MI optimization.  */
613*e4b17023SJohn Marino 		  pfile->buffer->need_line = true;
614*e4b17023SJohn Marino 		  CPP_INCREMENT_LINE (pfile, 0);
615*e4b17023SJohn Marino 		  result = false;
616*e4b17023SJohn Marino 		  goto done;
617*e4b17023SJohn Marino 		}
618*e4b17023SJohn Marino 	      else
619*e4b17023SJohn Marino 		{
620*e4b17023SJohn Marino 		  bool do_it = false;
621*e4b17023SJohn Marino 
622*e4b17023SJohn Marino 		  if (is_numstart (*cur)
623*e4b17023SJohn Marino 		      && CPP_OPTION (pfile, lang) != CLK_ASM)
624*e4b17023SJohn Marino 		    do_it = true;
625*e4b17023SJohn Marino 		  else if (is_idstart (*cur))
626*e4b17023SJohn Marino 		    /* Check whether we know this directive, but don't
627*e4b17023SJohn Marino 		       advance.  */
628*e4b17023SJohn Marino 		    do_it = lex_identifier (pfile, cur)->is_directive;
629*e4b17023SJohn Marino 
630*e4b17023SJohn Marino 		  if (do_it || CPP_OPTION (pfile, lang) != CLK_ASM)
631*e4b17023SJohn Marino 		    {
632*e4b17023SJohn Marino 		      /* This is a kludge.  We want to have the ISO
633*e4b17023SJohn Marino 			 preprocessor lex the next token.  */
634*e4b17023SJohn Marino 		      pfile->buffer->cur = cur;
635*e4b17023SJohn Marino 		      _cpp_handle_directive (pfile, false /* indented */);
636*e4b17023SJohn Marino 		      result = false;
637*e4b17023SJohn Marino 		      goto done;
638*e4b17023SJohn Marino 		    }
639*e4b17023SJohn Marino 		}
640*e4b17023SJohn Marino 	    }
641*e4b17023SJohn Marino 
642*e4b17023SJohn Marino 	  if (pfile->state.in_expression)
643*e4b17023SJohn Marino 	    {
644*e4b17023SJohn Marino 	      lex_state = ls_hash;
645*e4b17023SJohn Marino 	      continue;
646*e4b17023SJohn Marino 	    }
647*e4b17023SJohn Marino 	  break;
648*e4b17023SJohn Marino 
649*e4b17023SJohn Marino 	default:
650*e4b17023SJohn Marino 	  break;
651*e4b17023SJohn Marino 	}
652*e4b17023SJohn Marino 
653*e4b17023SJohn Marino       /* Non-whitespace disables MI optimization and stops treating
654*e4b17023SJohn Marino 	 '<' as a quote in #include.  */
655*e4b17023SJohn Marino       header_ok = false;
656*e4b17023SJohn Marino       if (!pfile->state.in_directive)
657*e4b17023SJohn Marino 	pfile->mi_valid = false;
658*e4b17023SJohn Marino 
659*e4b17023SJohn Marino       if (lex_state == ls_none)
660*e4b17023SJohn Marino 	continue;
661*e4b17023SJohn Marino 
662*e4b17023SJohn Marino       /* Some of these transitions of state are syntax errors.  The
663*e4b17023SJohn Marino 	 ISO preprocessor will issue errors later.  */
664*e4b17023SJohn Marino       if (lex_state == ls_fun_open)
665*e4b17023SJohn Marino 	/* Missing '('.  */
666*e4b17023SJohn Marino 	lex_state = ls_none;
667*e4b17023SJohn Marino       else if (lex_state == ls_hash
668*e4b17023SJohn Marino 	       || lex_state == ls_predicate
669*e4b17023SJohn Marino 	       || lex_state == ls_defined)
670*e4b17023SJohn Marino 	lex_state = ls_none;
671*e4b17023SJohn Marino 
672*e4b17023SJohn Marino       /* ls_answer and ls_defined_close keep going until ')'.  */
673*e4b17023SJohn Marino     }
674*e4b17023SJohn Marino 
675*e4b17023SJohn Marino  done:
676*e4b17023SJohn Marino   if (fmacro.buff)
677*e4b17023SJohn Marino     _cpp_release_buff (pfile, fmacro.buff);
678*e4b17023SJohn Marino 
679*e4b17023SJohn Marino   if (lex_state == ls_fun_close)
680*e4b17023SJohn Marino     cpp_error_with_line (pfile, CPP_DL_ERROR, fmacro.line, 0,
681*e4b17023SJohn Marino 			 "unterminated argument list invoking macro \"%s\"",
682*e4b17023SJohn Marino 			 NODE_NAME (fmacro.node));
683*e4b17023SJohn Marino   return result;
684*e4b17023SJohn Marino }
685*e4b17023SJohn Marino 
686*e4b17023SJohn Marino /* Push a context holding the replacement text of the macro NODE on
687*e4b17023SJohn Marino    the context stack.  NODE is either object-like, or a function-like
688*e4b17023SJohn Marino    macro with no arguments.  */
689*e4b17023SJohn Marino static void
push_replacement_text(cpp_reader * pfile,cpp_hashnode * node)690*e4b17023SJohn Marino push_replacement_text (cpp_reader *pfile, cpp_hashnode *node)
691*e4b17023SJohn Marino {
692*e4b17023SJohn Marino   size_t len;
693*e4b17023SJohn Marino   const uchar *text;
694*e4b17023SJohn Marino   uchar *buf;
695*e4b17023SJohn Marino 
696*e4b17023SJohn Marino   if (node->flags & NODE_BUILTIN)
697*e4b17023SJohn Marino     {
698*e4b17023SJohn Marino       text = _cpp_builtin_macro_text (pfile, node);
699*e4b17023SJohn Marino       len = ustrlen (text);
700*e4b17023SJohn Marino       buf = _cpp_unaligned_alloc (pfile, len + 1);
701*e4b17023SJohn Marino       memcpy (buf, text, len);
702*e4b17023SJohn Marino       buf[len]='\n';
703*e4b17023SJohn Marino       text = buf;
704*e4b17023SJohn Marino     }
705*e4b17023SJohn Marino   else
706*e4b17023SJohn Marino     {
707*e4b17023SJohn Marino       cpp_macro *macro = node->value.macro;
708*e4b17023SJohn Marino       macro->used = 1;
709*e4b17023SJohn Marino       text = macro->exp.text;
710*e4b17023SJohn Marino       macro->traditional = 1;
711*e4b17023SJohn Marino       len = macro->count;
712*e4b17023SJohn Marino     }
713*e4b17023SJohn Marino 
714*e4b17023SJohn Marino   _cpp_push_text_context (pfile, node, text, len);
715*e4b17023SJohn Marino }
716*e4b17023SJohn Marino 
717*e4b17023SJohn Marino /* Returns TRUE if traditional macro recursion is detected.  */
718*e4b17023SJohn Marino static bool
recursive_macro(cpp_reader * pfile,cpp_hashnode * node)719*e4b17023SJohn Marino recursive_macro (cpp_reader *pfile, cpp_hashnode *node)
720*e4b17023SJohn Marino {
721*e4b17023SJohn Marino   bool recursing = !!(node->flags & NODE_DISABLED);
722*e4b17023SJohn Marino 
723*e4b17023SJohn Marino   /* Object-like macros that are already expanding are necessarily
724*e4b17023SJohn Marino      recursive.
725*e4b17023SJohn Marino 
726*e4b17023SJohn Marino      However, it is possible to have traditional function-like macros
727*e4b17023SJohn Marino      that are not infinitely recursive but recurse to any given depth.
728*e4b17023SJohn Marino      Further, it is easy to construct examples that get ever longer
729*e4b17023SJohn Marino      until the point they stop recursing.  So there is no easy way to
730*e4b17023SJohn Marino      detect true recursion; instead we assume any expansion more than
731*e4b17023SJohn Marino      20 deep since the first invocation of this macro must be
732*e4b17023SJohn Marino      recursing.  */
733*e4b17023SJohn Marino   if (recursing && node->value.macro->fun_like)
734*e4b17023SJohn Marino     {
735*e4b17023SJohn Marino       size_t depth = 0;
736*e4b17023SJohn Marino       cpp_context *context = pfile->context;
737*e4b17023SJohn Marino 
738*e4b17023SJohn Marino       do
739*e4b17023SJohn Marino 	{
740*e4b17023SJohn Marino 	  depth++;
741*e4b17023SJohn Marino 	  if (context->c.macro == node && depth > 20)
742*e4b17023SJohn Marino 	    break;
743*e4b17023SJohn Marino 	  context = context->prev;
744*e4b17023SJohn Marino 	}
745*e4b17023SJohn Marino       while (context);
746*e4b17023SJohn Marino       recursing = context != NULL;
747*e4b17023SJohn Marino     }
748*e4b17023SJohn Marino 
749*e4b17023SJohn Marino   if (recursing)
750*e4b17023SJohn Marino     cpp_error (pfile, CPP_DL_ERROR,
751*e4b17023SJohn Marino 	       "detected recursion whilst expanding macro \"%s\"",
752*e4b17023SJohn Marino 	       NODE_NAME (node));
753*e4b17023SJohn Marino 
754*e4b17023SJohn Marino   return recursing;
755*e4b17023SJohn Marino }
756*e4b17023SJohn Marino 
757*e4b17023SJohn Marino /* Return the length of the replacement text of a function-like or
758*e4b17023SJohn Marino    object-like non-builtin macro.  */
759*e4b17023SJohn Marino size_t
_cpp_replacement_text_len(const cpp_macro * macro)760*e4b17023SJohn Marino _cpp_replacement_text_len (const cpp_macro *macro)
761*e4b17023SJohn Marino {
762*e4b17023SJohn Marino   size_t len;
763*e4b17023SJohn Marino 
764*e4b17023SJohn Marino   if (macro->fun_like && (macro->paramc != 0))
765*e4b17023SJohn Marino     {
766*e4b17023SJohn Marino       const uchar *exp;
767*e4b17023SJohn Marino 
768*e4b17023SJohn Marino       len = 0;
769*e4b17023SJohn Marino       for (exp = macro->exp.text;;)
770*e4b17023SJohn Marino 	{
771*e4b17023SJohn Marino 	  struct block *b = (struct block *) exp;
772*e4b17023SJohn Marino 
773*e4b17023SJohn Marino 	  len += b->text_len;
774*e4b17023SJohn Marino 	  if (b->arg_index == 0)
775*e4b17023SJohn Marino 	    break;
776*e4b17023SJohn Marino 	  len += NODE_LEN (macro->params[b->arg_index - 1]);
777*e4b17023SJohn Marino 	  exp += BLOCK_LEN (b->text_len);
778*e4b17023SJohn Marino 	}
779*e4b17023SJohn Marino     }
780*e4b17023SJohn Marino   else
781*e4b17023SJohn Marino     len = macro->count;
782*e4b17023SJohn Marino 
783*e4b17023SJohn Marino   return len;
784*e4b17023SJohn Marino }
785*e4b17023SJohn Marino 
786*e4b17023SJohn Marino /* Copy the replacement text of MACRO to DEST, which must be of
787*e4b17023SJohn Marino    sufficient size.  It is not NUL-terminated.  The next character is
788*e4b17023SJohn Marino    returned.  */
789*e4b17023SJohn Marino uchar *
_cpp_copy_replacement_text(const cpp_macro * macro,uchar * dest)790*e4b17023SJohn Marino _cpp_copy_replacement_text (const cpp_macro *macro, uchar *dest)
791*e4b17023SJohn Marino {
792*e4b17023SJohn Marino   if (macro->fun_like && (macro->paramc != 0))
793*e4b17023SJohn Marino     {
794*e4b17023SJohn Marino       const uchar *exp;
795*e4b17023SJohn Marino 
796*e4b17023SJohn Marino       for (exp = macro->exp.text;;)
797*e4b17023SJohn Marino 	{
798*e4b17023SJohn Marino 	  struct block *b = (struct block *) exp;
799*e4b17023SJohn Marino 	  cpp_hashnode *param;
800*e4b17023SJohn Marino 
801*e4b17023SJohn Marino 	  memcpy (dest, b->text, b->text_len);
802*e4b17023SJohn Marino 	  dest += b->text_len;
803*e4b17023SJohn Marino 	  if (b->arg_index == 0)
804*e4b17023SJohn Marino 	    break;
805*e4b17023SJohn Marino 	  param = macro->params[b->arg_index - 1];
806*e4b17023SJohn Marino 	  memcpy (dest, NODE_NAME (param), NODE_LEN (param));
807*e4b17023SJohn Marino 	  dest += NODE_LEN (param);
808*e4b17023SJohn Marino 	  exp += BLOCK_LEN (b->text_len);
809*e4b17023SJohn Marino 	}
810*e4b17023SJohn Marino     }
811*e4b17023SJohn Marino   else
812*e4b17023SJohn Marino     {
813*e4b17023SJohn Marino       memcpy (dest, macro->exp.text, macro->count);
814*e4b17023SJohn Marino       dest += macro->count;
815*e4b17023SJohn Marino     }
816*e4b17023SJohn Marino 
817*e4b17023SJohn Marino   return dest;
818*e4b17023SJohn Marino }
819*e4b17023SJohn Marino 
820*e4b17023SJohn Marino /* Push a context holding the replacement text of the macro NODE on
821*e4b17023SJohn Marino    the context stack.  NODE is either object-like, or a function-like
822*e4b17023SJohn Marino    macro with no arguments.  */
823*e4b17023SJohn Marino static void
replace_args_and_push(cpp_reader * pfile,struct fun_macro * fmacro)824*e4b17023SJohn Marino replace_args_and_push (cpp_reader *pfile, struct fun_macro *fmacro)
825*e4b17023SJohn Marino {
826*e4b17023SJohn Marino   cpp_macro *macro = fmacro->node->value.macro;
827*e4b17023SJohn Marino 
828*e4b17023SJohn Marino   if (macro->paramc == 0)
829*e4b17023SJohn Marino     push_replacement_text (pfile, fmacro->node);
830*e4b17023SJohn Marino   else
831*e4b17023SJohn Marino     {
832*e4b17023SJohn Marino       const uchar *exp;
833*e4b17023SJohn Marino       uchar *p;
834*e4b17023SJohn Marino       _cpp_buff *buff;
835*e4b17023SJohn Marino       size_t len = 0;
836*e4b17023SJohn Marino       int cxtquote = 0;
837*e4b17023SJohn Marino 
838*e4b17023SJohn Marino       /* Get an estimate of the length of the argument-replaced text.
839*e4b17023SJohn Marino 	 This is a worst case estimate, assuming that every replacement
840*e4b17023SJohn Marino 	 text character needs quoting.  */
841*e4b17023SJohn Marino       for (exp = macro->exp.text;;)
842*e4b17023SJohn Marino 	{
843*e4b17023SJohn Marino 	  struct block *b = (struct block *) exp;
844*e4b17023SJohn Marino 
845*e4b17023SJohn Marino 	  len += b->text_len;
846*e4b17023SJohn Marino 	  if (b->arg_index == 0)
847*e4b17023SJohn Marino 	    break;
848*e4b17023SJohn Marino 	  len += 2 * (fmacro->args[b->arg_index]
849*e4b17023SJohn Marino 		      - fmacro->args[b->arg_index - 1] - 1);
850*e4b17023SJohn Marino 	  exp += BLOCK_LEN (b->text_len);
851*e4b17023SJohn Marino 	}
852*e4b17023SJohn Marino 
853*e4b17023SJohn Marino       /* Allocate room for the expansion plus \n.  */
854*e4b17023SJohn Marino       buff = _cpp_get_buff (pfile, len + 1);
855*e4b17023SJohn Marino 
856*e4b17023SJohn Marino       /* Copy the expansion and replace arguments.  */
857*e4b17023SJohn Marino       /* Accumulate actual length, including quoting as necessary */
858*e4b17023SJohn Marino       p = BUFF_FRONT (buff);
859*e4b17023SJohn Marino       len = 0;
860*e4b17023SJohn Marino       for (exp = macro->exp.text;;)
861*e4b17023SJohn Marino 	{
862*e4b17023SJohn Marino 	  struct block *b = (struct block *) exp;
863*e4b17023SJohn Marino 	  size_t arglen;
864*e4b17023SJohn Marino 	  int argquote;
865*e4b17023SJohn Marino 	  uchar *base;
866*e4b17023SJohn Marino 	  uchar *in;
867*e4b17023SJohn Marino 
868*e4b17023SJohn Marino 	  len += b->text_len;
869*e4b17023SJohn Marino 	  /* Copy the non-argument text literally, keeping
870*e4b17023SJohn Marino 	     track of whether matching quotes have been seen. */
871*e4b17023SJohn Marino 	  for (arglen = b->text_len, in = b->text; arglen > 0; arglen--)
872*e4b17023SJohn Marino 	    {
873*e4b17023SJohn Marino 	      if (*in == '"')
874*e4b17023SJohn Marino 		cxtquote = ! cxtquote;
875*e4b17023SJohn Marino 	      *p++ = *in++;
876*e4b17023SJohn Marino 	    }
877*e4b17023SJohn Marino 	  /* Done if no more arguments */
878*e4b17023SJohn Marino 	  if (b->arg_index == 0)
879*e4b17023SJohn Marino 	    break;
880*e4b17023SJohn Marino 	  arglen = (fmacro->args[b->arg_index]
881*e4b17023SJohn Marino 		    - fmacro->args[b->arg_index - 1] - 1);
882*e4b17023SJohn Marino 	  base = pfile->out.base + fmacro->args[b->arg_index - 1];
883*e4b17023SJohn Marino 	  in = base;
884*e4b17023SJohn Marino #if 0
885*e4b17023SJohn Marino 	  /* Skip leading whitespace in the text for the argument to
886*e4b17023SJohn Marino 	     be substituted. To be compatible with gcc 2.95, we would
887*e4b17023SJohn Marino 	     also need to trim trailing whitespace. Gcc 2.95 trims
888*e4b17023SJohn Marino 	     leading and trailing whitespace, which may be a bug.  The
889*e4b17023SJohn Marino 	     current gcc testsuite explicitly checks that this leading
890*e4b17023SJohn Marino 	     and trailing whitespace in actual arguments is
891*e4b17023SJohn Marino 	     preserved. */
892*e4b17023SJohn Marino 	  while (arglen > 0 && is_space (*in))
893*e4b17023SJohn Marino 	    {
894*e4b17023SJohn Marino 	      in++;
895*e4b17023SJohn Marino 	      arglen--;
896*e4b17023SJohn Marino 	    }
897*e4b17023SJohn Marino #endif
898*e4b17023SJohn Marino 	  for (argquote = 0; arglen > 0; arglen--)
899*e4b17023SJohn Marino 	    {
900*e4b17023SJohn Marino 	      if (cxtquote && *in == '"')
901*e4b17023SJohn Marino 		{
902*e4b17023SJohn Marino 		  if (in > base && *(in-1) != '\\')
903*e4b17023SJohn Marino 		    argquote = ! argquote;
904*e4b17023SJohn Marino 		  /* Always add backslash before double quote if argument
905*e4b17023SJohn Marino 		     is expanded in a quoted context */
906*e4b17023SJohn Marino 		  *p++ = '\\';
907*e4b17023SJohn Marino 		  len++;
908*e4b17023SJohn Marino 		}
909*e4b17023SJohn Marino 	      else if (cxtquote && argquote && *in == '\\')
910*e4b17023SJohn Marino 		{
911*e4b17023SJohn Marino 		  /* Always add backslash before a backslash in an argument
912*e4b17023SJohn Marino 		     that is expanded in a quoted context and also in the
913*e4b17023SJohn Marino 		     range of a quoted context in the argument itself. */
914*e4b17023SJohn Marino 		  *p++ = '\\';
915*e4b17023SJohn Marino 		  len++;
916*e4b17023SJohn Marino 		}
917*e4b17023SJohn Marino 	      *p++ = *in++;
918*e4b17023SJohn Marino 	      len++;
919*e4b17023SJohn Marino 	    }
920*e4b17023SJohn Marino 	  exp += BLOCK_LEN (b->text_len);
921*e4b17023SJohn Marino 	}
922*e4b17023SJohn Marino 
923*e4b17023SJohn Marino       /* \n-terminate.  */
924*e4b17023SJohn Marino       *p = '\n';
925*e4b17023SJohn Marino       _cpp_push_text_context (pfile, fmacro->node, BUFF_FRONT (buff), len);
926*e4b17023SJohn Marino 
927*e4b17023SJohn Marino       /* So we free buffer allocation when macro is left.  */
928*e4b17023SJohn Marino       pfile->context->buff = buff;
929*e4b17023SJohn Marino     }
930*e4b17023SJohn Marino }
931*e4b17023SJohn Marino 
932*e4b17023SJohn Marino /* Read and record the parameters, if any, of a function-like macro
933*e4b17023SJohn Marino    definition.  Destroys pfile->out.cur.
934*e4b17023SJohn Marino 
935*e4b17023SJohn Marino    Returns true on success, false on failure (syntax error or a
936*e4b17023SJohn Marino    duplicate parameter).  On success, CUR (pfile->context) is just
937*e4b17023SJohn Marino    past the closing parenthesis.  */
938*e4b17023SJohn Marino static bool
scan_parameters(cpp_reader * pfile,cpp_macro * macro)939*e4b17023SJohn Marino scan_parameters (cpp_reader *pfile, cpp_macro *macro)
940*e4b17023SJohn Marino {
941*e4b17023SJohn Marino   const uchar *cur = CUR (pfile->context) + 1;
942*e4b17023SJohn Marino   bool ok;
943*e4b17023SJohn Marino 
944*e4b17023SJohn Marino   for (;;)
945*e4b17023SJohn Marino     {
946*e4b17023SJohn Marino       cur = skip_whitespace (pfile, cur, true /* skip_comments */);
947*e4b17023SJohn Marino 
948*e4b17023SJohn Marino       if (is_idstart (*cur))
949*e4b17023SJohn Marino 	{
950*e4b17023SJohn Marino 	  ok = false;
951*e4b17023SJohn Marino 	  if (_cpp_save_parameter (pfile, macro, lex_identifier (pfile, cur)))
952*e4b17023SJohn Marino 	    break;
953*e4b17023SJohn Marino 	  cur = skip_whitespace (pfile, CUR (pfile->context),
954*e4b17023SJohn Marino 				 true /* skip_comments */);
955*e4b17023SJohn Marino 	  if (*cur == ',')
956*e4b17023SJohn Marino 	    {
957*e4b17023SJohn Marino 	      cur++;
958*e4b17023SJohn Marino 	      continue;
959*e4b17023SJohn Marino 	    }
960*e4b17023SJohn Marino 	  ok = (*cur == ')');
961*e4b17023SJohn Marino 	  break;
962*e4b17023SJohn Marino 	}
963*e4b17023SJohn Marino 
964*e4b17023SJohn Marino       ok = (*cur == ')' && macro->paramc == 0);
965*e4b17023SJohn Marino       break;
966*e4b17023SJohn Marino     }
967*e4b17023SJohn Marino 
968*e4b17023SJohn Marino   if (!ok)
969*e4b17023SJohn Marino     cpp_error (pfile, CPP_DL_ERROR, "syntax error in macro parameter list");
970*e4b17023SJohn Marino 
971*e4b17023SJohn Marino   CUR (pfile->context) = cur + (*cur == ')');
972*e4b17023SJohn Marino 
973*e4b17023SJohn Marino   return ok;
974*e4b17023SJohn Marino }
975*e4b17023SJohn Marino 
976*e4b17023SJohn Marino /* Save the text from pfile->out.base to pfile->out.cur as
977*e4b17023SJohn Marino    the replacement text for the current macro, followed by argument
978*e4b17023SJohn Marino    ARG_INDEX, with zero indicating the end of the replacement
979*e4b17023SJohn Marino    text.  */
980*e4b17023SJohn Marino static void
save_replacement_text(cpp_reader * pfile,cpp_macro * macro,unsigned int arg_index)981*e4b17023SJohn Marino save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
982*e4b17023SJohn Marino 		       unsigned int arg_index)
983*e4b17023SJohn Marino {
984*e4b17023SJohn Marino   size_t len = pfile->out.cur - pfile->out.base;
985*e4b17023SJohn Marino   uchar *exp;
986*e4b17023SJohn Marino 
987*e4b17023SJohn Marino   if (macro->paramc == 0)
988*e4b17023SJohn Marino     {
989*e4b17023SJohn Marino       /* Object-like and function-like macros without parameters
990*e4b17023SJohn Marino 	 simply store their \n-terminated replacement text.  */
991*e4b17023SJohn Marino       exp = _cpp_unaligned_alloc (pfile, len + 1);
992*e4b17023SJohn Marino       memcpy (exp, pfile->out.base, len);
993*e4b17023SJohn Marino       exp[len] = '\n';
994*e4b17023SJohn Marino       macro->exp.text = exp;
995*e4b17023SJohn Marino       macro->traditional = 1;
996*e4b17023SJohn Marino       macro->count = len;
997*e4b17023SJohn Marino     }
998*e4b17023SJohn Marino   else
999*e4b17023SJohn Marino     {
1000*e4b17023SJohn Marino       /* Store the text's length (unsigned int), the argument index
1001*e4b17023SJohn Marino 	 (unsigned short, base 1) and then the text.  */
1002*e4b17023SJohn Marino       size_t blen = BLOCK_LEN (len);
1003*e4b17023SJohn Marino       struct block *block;
1004*e4b17023SJohn Marino 
1005*e4b17023SJohn Marino       if (macro->count + blen > BUFF_ROOM (pfile->a_buff))
1006*e4b17023SJohn Marino 	_cpp_extend_buff (pfile, &pfile->a_buff, macro->count + blen);
1007*e4b17023SJohn Marino 
1008*e4b17023SJohn Marino       exp = BUFF_FRONT (pfile->a_buff);
1009*e4b17023SJohn Marino       block = (struct block *) (exp + macro->count);
1010*e4b17023SJohn Marino       macro->exp.text = exp;
1011*e4b17023SJohn Marino       macro->traditional = 1;
1012*e4b17023SJohn Marino 
1013*e4b17023SJohn Marino       /* Write out the block information.  */
1014*e4b17023SJohn Marino       block->text_len = len;
1015*e4b17023SJohn Marino       block->arg_index = arg_index;
1016*e4b17023SJohn Marino       memcpy (block->text, pfile->out.base, len);
1017*e4b17023SJohn Marino 
1018*e4b17023SJohn Marino       /* Lex the rest into the start of the output buffer.  */
1019*e4b17023SJohn Marino       pfile->out.cur = pfile->out.base;
1020*e4b17023SJohn Marino 
1021*e4b17023SJohn Marino       macro->count += blen;
1022*e4b17023SJohn Marino 
1023*e4b17023SJohn Marino       /* If we've finished, commit the memory.  */
1024*e4b17023SJohn Marino       if (arg_index == 0)
1025*e4b17023SJohn Marino 	BUFF_FRONT (pfile->a_buff) += macro->count;
1026*e4b17023SJohn Marino     }
1027*e4b17023SJohn Marino }
1028*e4b17023SJohn Marino 
1029*e4b17023SJohn Marino /* Analyze and save the replacement text of a macro.  Returns true on
1030*e4b17023SJohn Marino    success.  */
1031*e4b17023SJohn Marino bool
_cpp_create_trad_definition(cpp_reader * pfile,cpp_macro * macro)1032*e4b17023SJohn Marino _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
1033*e4b17023SJohn Marino {
1034*e4b17023SJohn Marino   const uchar *cur;
1035*e4b17023SJohn Marino   uchar *limit;
1036*e4b17023SJohn Marino   cpp_context *context = pfile->context;
1037*e4b17023SJohn Marino 
1038*e4b17023SJohn Marino   /* The context has not been set up for command line defines, and CUR
1039*e4b17023SJohn Marino      has not been updated for the macro name for in-file defines.  */
1040*e4b17023SJohn Marino   pfile->out.cur = pfile->out.base;
1041*e4b17023SJohn Marino   CUR (context) = pfile->buffer->cur;
1042*e4b17023SJohn Marino   RLIMIT (context) = pfile->buffer->rlimit;
1043*e4b17023SJohn Marino   check_output_buffer (pfile, RLIMIT (context) - CUR (context));
1044*e4b17023SJohn Marino 
1045*e4b17023SJohn Marino   /* Is this a function-like macro?  */
1046*e4b17023SJohn Marino   if (* CUR (context) == '(')
1047*e4b17023SJohn Marino     {
1048*e4b17023SJohn Marino       bool ok = scan_parameters (pfile, macro);
1049*e4b17023SJohn Marino 
1050*e4b17023SJohn Marino       /* Remember the params so we can clear NODE_MACRO_ARG flags.  */
1051*e4b17023SJohn Marino       macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
1052*e4b17023SJohn Marino 
1053*e4b17023SJohn Marino       /* Setting macro to NULL indicates an error occurred, and
1054*e4b17023SJohn Marino 	 prevents unnecessary work in _cpp_scan_out_logical_line.  */
1055*e4b17023SJohn Marino       if (!ok)
1056*e4b17023SJohn Marino 	macro = NULL;
1057*e4b17023SJohn Marino       else
1058*e4b17023SJohn Marino 	{
1059*e4b17023SJohn Marino 	  BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
1060*e4b17023SJohn Marino 	  macro->fun_like = 1;
1061*e4b17023SJohn Marino 	}
1062*e4b17023SJohn Marino     }
1063*e4b17023SJohn Marino 
1064*e4b17023SJohn Marino   /* Skip leading whitespace in the replacement text.  */
1065*e4b17023SJohn Marino   pfile->buffer->cur
1066*e4b17023SJohn Marino     = skip_whitespace (pfile, CUR (context),
1067*e4b17023SJohn Marino 		       CPP_OPTION (pfile, discard_comments_in_macro_exp));
1068*e4b17023SJohn Marino 
1069*e4b17023SJohn Marino   pfile->state.prevent_expansion++;
1070*e4b17023SJohn Marino   _cpp_scan_out_logical_line (pfile, macro);
1071*e4b17023SJohn Marino   pfile->state.prevent_expansion--;
1072*e4b17023SJohn Marino 
1073*e4b17023SJohn Marino   if (!macro)
1074*e4b17023SJohn Marino     return false;
1075*e4b17023SJohn Marino 
1076*e4b17023SJohn Marino   /* Skip trailing white space.  */
1077*e4b17023SJohn Marino   cur = pfile->out.base;
1078*e4b17023SJohn Marino   limit = pfile->out.cur;
1079*e4b17023SJohn Marino   while (limit > cur && is_space (limit[-1]))
1080*e4b17023SJohn Marino     limit--;
1081*e4b17023SJohn Marino   pfile->out.cur = limit;
1082*e4b17023SJohn Marino   save_replacement_text (pfile, macro, 0);
1083*e4b17023SJohn Marino 
1084*e4b17023SJohn Marino   return true;
1085*e4b17023SJohn Marino }
1086*e4b17023SJohn Marino 
1087*e4b17023SJohn Marino /* Copy SRC of length LEN to DEST, but convert all contiguous
1088*e4b17023SJohn Marino    whitespace to a single space, provided it is not in quotes.  The
1089*e4b17023SJohn Marino    quote currently in effect is pointed to by PQUOTE, and is updated
1090*e4b17023SJohn Marino    by the function.  Returns the number of bytes copied.  */
1091*e4b17023SJohn Marino static size_t
canonicalize_text(uchar * dest,const uchar * src,size_t len,uchar * pquote)1092*e4b17023SJohn Marino canonicalize_text (uchar *dest, const uchar *src, size_t len, uchar *pquote)
1093*e4b17023SJohn Marino {
1094*e4b17023SJohn Marino   uchar *orig_dest = dest;
1095*e4b17023SJohn Marino   uchar quote = *pquote;
1096*e4b17023SJohn Marino 
1097*e4b17023SJohn Marino   while (len)
1098*e4b17023SJohn Marino     {
1099*e4b17023SJohn Marino       if (is_space (*src) && !quote)
1100*e4b17023SJohn Marino 	{
1101*e4b17023SJohn Marino 	  do
1102*e4b17023SJohn Marino 	    src++, len--;
1103*e4b17023SJohn Marino 	  while (len && is_space (*src));
1104*e4b17023SJohn Marino 	  *dest++ = ' ';
1105*e4b17023SJohn Marino 	}
1106*e4b17023SJohn Marino       else
1107*e4b17023SJohn Marino 	{
1108*e4b17023SJohn Marino 	  if (*src == '\'' || *src == '"')
1109*e4b17023SJohn Marino 	    {
1110*e4b17023SJohn Marino 	      if (!quote)
1111*e4b17023SJohn Marino 		quote = *src;
1112*e4b17023SJohn Marino 	      else if (quote == *src)
1113*e4b17023SJohn Marino 		quote = 0;
1114*e4b17023SJohn Marino 	    }
1115*e4b17023SJohn Marino 	  *dest++ = *src++, len--;
1116*e4b17023SJohn Marino 	}
1117*e4b17023SJohn Marino     }
1118*e4b17023SJohn Marino 
1119*e4b17023SJohn Marino   *pquote = quote;
1120*e4b17023SJohn Marino   return dest - orig_dest;
1121*e4b17023SJohn Marino }
1122*e4b17023SJohn Marino 
1123*e4b17023SJohn Marino /* Returns true if MACRO1 and MACRO2 have expansions different other
1124*e4b17023SJohn Marino    than in the form of their whitespace.  */
1125*e4b17023SJohn Marino bool
_cpp_expansions_different_trad(const cpp_macro * macro1,const cpp_macro * macro2)1126*e4b17023SJohn Marino _cpp_expansions_different_trad (const cpp_macro *macro1,
1127*e4b17023SJohn Marino 				const cpp_macro *macro2)
1128*e4b17023SJohn Marino {
1129*e4b17023SJohn Marino   uchar *p1 = XNEWVEC (uchar, macro1->count + macro2->count);
1130*e4b17023SJohn Marino   uchar *p2 = p1 + macro1->count;
1131*e4b17023SJohn Marino   uchar quote1 = 0, quote2 = 0;
1132*e4b17023SJohn Marino   bool mismatch;
1133*e4b17023SJohn Marino   size_t len1, len2;
1134*e4b17023SJohn Marino 
1135*e4b17023SJohn Marino   if (macro1->paramc > 0)
1136*e4b17023SJohn Marino     {
1137*e4b17023SJohn Marino       const uchar *exp1 = macro1->exp.text, *exp2 = macro2->exp.text;
1138*e4b17023SJohn Marino 
1139*e4b17023SJohn Marino       mismatch = true;
1140*e4b17023SJohn Marino       for (;;)
1141*e4b17023SJohn Marino 	{
1142*e4b17023SJohn Marino 	  struct block *b1 = (struct block *) exp1;
1143*e4b17023SJohn Marino 	  struct block *b2 = (struct block *) exp2;
1144*e4b17023SJohn Marino 
1145*e4b17023SJohn Marino 	  if (b1->arg_index != b2->arg_index)
1146*e4b17023SJohn Marino 	    break;
1147*e4b17023SJohn Marino 
1148*e4b17023SJohn Marino 	  len1 = canonicalize_text (p1, b1->text, b1->text_len, &quote1);
1149*e4b17023SJohn Marino 	  len2 = canonicalize_text (p2, b2->text, b2->text_len, &quote2);
1150*e4b17023SJohn Marino 	  if (len1 != len2 || memcmp (p1, p2, len1))
1151*e4b17023SJohn Marino 	    break;
1152*e4b17023SJohn Marino 	  if (b1->arg_index == 0)
1153*e4b17023SJohn Marino 	    {
1154*e4b17023SJohn Marino 	      mismatch = false;
1155*e4b17023SJohn Marino 	      break;
1156*e4b17023SJohn Marino 	    }
1157*e4b17023SJohn Marino 	  exp1 += BLOCK_LEN (b1->text_len);
1158*e4b17023SJohn Marino 	  exp2 += BLOCK_LEN (b2->text_len);
1159*e4b17023SJohn Marino 	}
1160*e4b17023SJohn Marino     }
1161*e4b17023SJohn Marino   else
1162*e4b17023SJohn Marino     {
1163*e4b17023SJohn Marino       len1 = canonicalize_text (p1, macro1->exp.text, macro1->count, &quote1);
1164*e4b17023SJohn Marino       len2 = canonicalize_text (p2, macro2->exp.text, macro2->count, &quote2);
1165*e4b17023SJohn Marino       mismatch = (len1 != len2 || memcmp (p1, p2, len1));
1166*e4b17023SJohn Marino     }
1167*e4b17023SJohn Marino 
1168*e4b17023SJohn Marino   free (p1);
1169*e4b17023SJohn Marino   return mismatch;
1170*e4b17023SJohn Marino }
1171