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