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