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 *) ¯o->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, "e1);
1092*404b540aSrobert len2 = canonicalize_text (p2, b2->text, b2->text_len, "e2);
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, "e1);
1107*404b540aSrobert len2 = canonicalize_text (p2, macro2->exp.text, macro2->count, "e2);
1108*404b540aSrobert mismatch = (len1 != len2 || memcmp (p1, p2, len1));
1109*404b540aSrobert }
1110*404b540aSrobert
1111*404b540aSrobert free (p1);
1112*404b540aSrobert return mismatch;
1113*404b540aSrobert }
1114