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