/* CPP Library - traditional lexical analysis and macro expansion.
   Copyright (C) 2002-2020 Free Software Foundation, Inc.
   Contributed by Neil Booth, May 2002

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "cpplib.h"
#include "internal.h"

/* The replacement text of a function-like macro is stored as a
   contiguous sequence of aligned blocks, each representing the text
   between subsequent parameters.

   Each block comprises the text between its surrounding parameters,
   the length of that text, and the one-based index of the following
   parameter.  The final block in the replacement text is easily
   recognizable as it has an argument index of zero.  */

struct block
{
  unsigned int text_len;
  unsigned short arg_index;
  uchar text[1];
};

#define BLOCK_HEADER_LEN offsetof (struct block, text)
#define BLOCK_LEN(TEXT_LEN) CPP_ALIGN (BLOCK_HEADER_LEN + (TEXT_LEN))

/* Structure holding information about a function-like macro
   invocation.  */
struct fun_macro
{
  /* Memory buffer holding the trad_arg array.  */
  _cpp_buff *buff;

  /* An array of size the number of macro parameters + 1, containing
     the offsets of the start of each macro argument in the output
     buffer.  The argument continues until the character before the
     start of the next one.  */
  size_t *args;

  /* The hashnode of the macro.  */
  cpp_hashnode *node;

  /* The offset of the macro name in the output buffer.  */
  size_t offset;

  /* The line the macro name appeared on.  */
  location_t line;

  /* Number of parameters.  */
  unsigned int paramc;

  /* Zero-based index of argument being currently lexed.  */
  unsigned int argc;
};

/* Lexing state.  It is mostly used to prevent macro expansion.  */
enum ls {ls_none = 0,		/* Normal state.  */
	 ls_fun_open,		/* When looking for '('.  */
	 ls_fun_close,		/* When looking for ')'.  */
	 ls_defined,		/* After defined.  */
	 ls_defined_close,	/* Looking for ')' of defined().  */
	 ls_hash,		/* After # in preprocessor conditional.  */
	 ls_predicate,		/* After the predicate, maybe paren?  */
	 ls_answer		/* In answer to predicate.  */
};

/* Lexing TODO: Maybe handle space in escaped newlines.  Stop lex.c
   from recognizing comments and directives during its lexing pass.  */

static const uchar *skip_whitespace (cpp_reader *, const uchar *, int);
static cpp_hashnode *lex_identifier (cpp_reader *, const uchar *);
static const uchar *copy_comment (cpp_reader *, const uchar *, int);
static void check_output_buffer (cpp_reader *, size_t);
static void push_replacement_text (cpp_reader *, cpp_hashnode *);
static bool scan_parameters (cpp_reader *, unsigned *);
static bool recursive_macro (cpp_reader *, cpp_hashnode *);
static void save_replacement_text (cpp_reader *, cpp_macro *, unsigned int);
static void maybe_start_funlike (cpp_reader *, cpp_hashnode *, const uchar *,
				 struct fun_macro *);
static void save_argument (struct fun_macro *, size_t);
static void replace_args_and_push (cpp_reader *, struct fun_macro *);
static size_t canonicalize_text (uchar *, const uchar *, size_t, uchar *);

/* Ensures we have N bytes' space in the output buffer, and
   reallocates it if not.  */
static void
check_output_buffer (cpp_reader *pfile, size_t n)
{
  /* We might need two bytes to terminate an unterminated comment, and
     one more to terminate the line with a NUL.  */
  n += 2 + 1;

  if (n > (size_t) (pfile->out.limit - pfile->out.cur))
    {
      size_t size = pfile->out.cur - pfile->out.base;
      size_t new_size = (size + n) * 3 / 2;

      pfile->out.base = XRESIZEVEC (unsigned char, pfile->out.base, new_size);
      pfile->out.limit = pfile->out.base + new_size;
      pfile->out.cur = pfile->out.base + size;
    }
}

/* Skip a C-style block comment in a macro as a result of -CC.
   PFILE->buffer->cur points to the initial asterisk of the comment,
   change it to point to after the '*' and '/' characters that terminate it.
   Return true if the macro has not been termined, in that case set
   PFILE->buffer->cur to the end of the buffer.  */
static bool
skip_macro_block_comment (cpp_reader *pfile)
{
  const uchar *cur = pfile->buffer->cur;

  cur++;
  if (*cur == '/')
    cur++;

  /* People like decorating comments with '*', so check for '/'
     instead for efficiency.  */
  while (! (*cur++ == '/' && cur[-2] == '*'))
    if (cur[-1] == '\n')
      {
	pfile->buffer->cur = cur - 1;
	return true;
      }

  pfile->buffer->cur = cur;
  return false;
}

/* CUR points to the asterisk introducing a comment in the current
   context.  IN_DEFINE is true if we are in the replacement text of a
   macro.

   The asterisk and following comment is copied to the buffer pointed
   to by pfile->out.cur, which must be of sufficient size.
   Unterminated comments are diagnosed, and correctly terminated in
   the output.  pfile->out.cur is updated depending upon IN_DEFINE,
   -C, -CC and pfile->state.in_directive.

   Returns a pointer to the first character after the comment in the
   input buffer.  */
static const uchar *
copy_comment (cpp_reader *pfile, const uchar *cur, int in_define)
{
  bool unterminated, copy = false;
  location_t src_loc = pfile->line_table->highest_line;
  cpp_buffer *buffer = pfile->buffer;

  buffer->cur = cur;
  if (pfile->context->prev)
    unterminated = skip_macro_block_comment (pfile);
  else
    unterminated = _cpp_skip_block_comment (pfile);
    
  if (unterminated)
    cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0,
			 "unterminated comment");

  /* Comments in directives become spaces so that tokens are properly
     separated when the ISO preprocessor re-lexes the line.  The
     exception is #define.  */
  if (pfile->state.in_directive)
    {
      if (in_define)
	{
	  if (CPP_OPTION (pfile, discard_comments_in_macro_exp))
	    pfile->out.cur--;
	  else
	    copy = true;
	}
      else
	pfile->out.cur[-1] = ' ';
    }
  else if (CPP_OPTION (pfile, discard_comments))
    pfile->out.cur--;
  else
    copy = true;

  if (copy)
    {
      size_t len = (size_t) (buffer->cur - cur);
      memcpy (pfile->out.cur, cur, len);
      pfile->out.cur += len;
      if (unterminated)
	{
	  *pfile->out.cur++ = '*';
	  *pfile->out.cur++ = '/';
	}
    }

  return buffer->cur;
}

/* CUR points to any character in the input buffer.  Skips over all
   contiguous horizontal white space and NULs, including comments if
   SKIP_COMMENTS, until reaching the first non-horizontal-whitespace
   character or the end of the current context.  Escaped newlines are
   removed.

   The whitespace is copied verbatim to the output buffer, except that
   comments are handled as described in copy_comment().
   pfile->out.cur is updated.

   Returns a pointer to the first character after the whitespace in
   the input buffer.  */
static const uchar *
skip_whitespace (cpp_reader *pfile, const uchar *cur, int skip_comments)
{
  uchar *out = pfile->out.cur;

  for (;;)
    {
      unsigned int c = *cur++;
      *out++ = c;

      if (is_nvspace (c))
	continue;

      if (c == '/' && *cur == '*' && skip_comments)
	{
	  pfile->out.cur = out;
	  cur = copy_comment (pfile, cur, false /* in_define */);
	  out = pfile->out.cur;
	  continue;
	}

      out--;
      break;
    }

  pfile->out.cur = out;
  return cur - 1;
}

/* Lexes and outputs an identifier starting at CUR, which is assumed
   to point to a valid first character of an identifier.  Returns
   the hashnode, and updates out.cur.  */
static cpp_hashnode *
lex_identifier (cpp_reader *pfile, const uchar *cur)
{
  size_t len;
  uchar *out = pfile->out.cur;
  cpp_hashnode *result;

  do
    *out++ = *cur++;
  while (is_numchar (*cur));

  CUR (pfile->context) = cur;
  len = out - pfile->out.cur;
  result = CPP_HASHNODE (ht_lookup (pfile->hash_table, pfile->out.cur,
				    len, HT_ALLOC));
  pfile->out.cur = out;
  return result;
}

/* Overlays the true file buffer temporarily with text of length LEN
   starting at START.  The true buffer is restored upon calling
   restore_buff().  */
void
_cpp_overlay_buffer (cpp_reader *pfile, const uchar *start, size_t len)
{
  cpp_buffer *buffer = pfile->buffer;

  pfile->overlaid_buffer = buffer;
  pfile->saved_cur = buffer->cur;
  pfile->saved_rlimit = buffer->rlimit;
  pfile->saved_line_base = buffer->next_line;
  buffer->need_line = false;

  buffer->cur = start;
  buffer->line_base = start;
  buffer->rlimit = start + len;
}

/* Restores a buffer overlaid by _cpp_overlay_buffer().  */
void
_cpp_remove_overlay (cpp_reader *pfile)
{
  cpp_buffer *buffer = pfile->overlaid_buffer;

  buffer->cur = pfile->saved_cur;
  buffer->rlimit = pfile->saved_rlimit;
  buffer->line_base = pfile->saved_line_base;
  buffer->need_line = true;

  pfile->overlaid_buffer = NULL;
}

/* Reads a logical line into the output buffer.  Returns TRUE if there
   is more text left in the buffer.  */
bool
_cpp_read_logical_line_trad (cpp_reader *pfile)
{
  do
    {
      if (pfile->buffer->need_line && !_cpp_get_fresh_line (pfile))
	{
	  /* Now pop the buffer that _cpp_get_fresh_line did not.  */
	  _cpp_pop_buffer (pfile);
	  return false;
	}
    }
  while (!_cpp_scan_out_logical_line (pfile, NULL, false)
	 || pfile->state.skipping);

  return pfile->buffer != NULL;
}

/* Return true if NODE is a fun_like macro.  */
static inline bool
fun_like_macro (cpp_hashnode *node)
{
  if (cpp_builtin_macro_p (node))
    return (node->value.builtin == BT_HAS_ATTRIBUTE
	    || node->value.builtin == BT_HAS_BUILTIN);
  return node->value.macro->fun_like;
}

/* Set up state for finding the opening '(' of a function-like
   macro.  */
static void
maybe_start_funlike (cpp_reader *pfile, cpp_hashnode *node, const uchar *start,
		     struct fun_macro *macro)
{
  unsigned int n;
  if (cpp_builtin_macro_p (node))
    n = 1;
  else
    n = node->value.macro->paramc;

  if (macro->buff)
    _cpp_release_buff (pfile, macro->buff);
  macro->buff = _cpp_get_buff (pfile, (n + 1) * sizeof (size_t));
  macro->args = (size_t *) BUFF_FRONT (macro->buff);
  macro->node = node;
  macro->offset = start - pfile->out.base;
  macro->paramc = n;
  macro->argc = 0;
}

/* Save the OFFSET of the start of the next argument to MACRO.  */
static void
save_argument (struct fun_macro *macro, size_t offset)
{
  macro->argc++;
  if (macro->argc <= macro->paramc)
    macro->args[macro->argc] = offset;
}

/* Copies the next logical line in the current buffer (starting at
   buffer->cur) to the output buffer.  The output is guaranteed to
   terminate with a NUL character.  buffer->cur is updated.

   If MACRO is non-NULL, then we are scanning the replacement list of
   MACRO, and we call save_replacement_text() every time we meet an
   argument.

   If BUILTIN_MACRO_ARG is true, this is called to macro expand
   arguments of builtin function-like macros.  */
bool
_cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro,
			    bool builtin_macro_arg)
{
  bool result = true;
  cpp_context *context;
  const uchar *cur;
  uchar *out;
  struct fun_macro fmacro;
  unsigned int c, paren_depth = 0, quote;
  enum ls lex_state = ls_none;
  bool header_ok;
  const uchar *start_of_input_line;

  fmacro.buff = NULL;
  fmacro.args = NULL;
  fmacro.node = NULL;
  fmacro.offset = 0;
  fmacro.line = 0;
  fmacro.paramc = 0;
  fmacro.argc = 0;

  quote = 0;
  header_ok = pfile->state.angled_headers;
  CUR (pfile->context) = pfile->buffer->cur;
  RLIMIT (pfile->context) = pfile->buffer->rlimit;
  if (!builtin_macro_arg)
    {
      pfile->out.cur = pfile->out.base;
      pfile->out.first_line = pfile->line_table->highest_line;
    }
  /* start_of_input_line is needed to make sure that directives really,
     really start at the first character of the line.  */
  start_of_input_line = pfile->buffer->cur;
 new_context:
  context = pfile->context;
  cur = CUR (context);
  check_output_buffer (pfile, RLIMIT (context) - cur);
  out = pfile->out.cur;

  for (;;)
    {
      if (!context->prev
	  && !builtin_macro_arg
	  && cur >= pfile->buffer->notes[pfile->buffer->cur_note].pos)
	{
	  pfile->buffer->cur = cur;
	  _cpp_process_line_notes (pfile, false);
	}
      c = *cur++;
      *out++ = c;

      /* Whitespace should "continue" out of the switch,
	 non-whitespace should "break" out of it.  */
      switch (c)
	{
	case ' ':
	case '\t':
	case '\f':
	case '\v':
	case '\0':
	  continue;

	case '\n':
	  /* If this is a macro's expansion, pop it.  */
	  if (context->prev)
	    {
	      pfile->out.cur = out - 1;
	      _cpp_pop_context (pfile);
	      goto new_context;
	    }

	  /* Omit the newline from the output buffer.  */
	  pfile->out.cur = out - 1;
	  pfile->buffer->cur = cur;
	  if (builtin_macro_arg)
	    goto done;
	  pfile->buffer->need_line = true;
	  CPP_INCREMENT_LINE (pfile, 0);

	  if ((lex_state == ls_fun_open || lex_state == ls_fun_close)
	      && !pfile->state.in_directive
	      && _cpp_get_fresh_line (pfile))
	    {
	      /* Newlines in arguments become a space, but we don't
		 clear any in-progress quote.  */
	      if (lex_state == ls_fun_close)
		out[-1] = ' ';
	      cur = pfile->buffer->cur;
	      continue;
	    }
	  goto done;

	case '<':
	  if (header_ok)
	    quote = '>';
	  break;
	case '>':
	  if (c == quote)
	    quote = 0;
	  break;

	case '"':
	case '\'':
	  if (c == quote)
	    quote = 0;
	  else if (!quote)
	    quote = c;
	  break;

	case '\\':
	  /* Skip escaped quotes here, it's easier than above.  */
	  if (*cur == '\\' || *cur == '"' || *cur == '\'')
	    *out++ = *cur++;
	  break;

	case '/':
	  /* Traditional CPP does not recognize comments within
	     literals.  */
	  if (!quote && *cur == '*')
	    {
	      pfile->out.cur = out;
	      cur = copy_comment (pfile, cur, macro != 0);
	      out = pfile->out.cur;
	      continue;
	    }
	  break;

	case '_':
	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
	case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
	case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
	case 's': case 't': case 'u': case 'v': case 'w': case 'x':
	case 'y': case 'z':
	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
	case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
	case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
	case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
	case 'Y': case 'Z':
	  if (!pfile->state.skipping && (quote == 0 || macro))
	    {
	      cpp_hashnode *node;
	      uchar *out_start = out - 1;

	      pfile->out.cur = out_start;
	      node = lex_identifier (pfile, cur - 1);
	      out = pfile->out.cur;
	      cur = CUR (context);

	      if (cpp_macro_p (node)
		  /* Should we expand for ls_answer?  */
		  && (lex_state == ls_none || lex_state == ls_fun_open)
		  && !pfile->state.prevent_expansion)
		{
		  /* Macros invalidate MI optimization.  */
		  pfile->mi_valid = false;
		  if (fun_like_macro (node))
		    {
		      maybe_start_funlike (pfile, node, out_start, &fmacro);
		      lex_state = ls_fun_open;
		      fmacro.line = pfile->line_table->highest_line;
		      continue;
		    }
		  else if (!recursive_macro (pfile, node))
		    {
		      /* Remove the object-like macro's name from the
			 output, and push its replacement text.  */
		      pfile->out.cur = out_start;
		      push_replacement_text (pfile, node);
		      lex_state = ls_none;
		      goto new_context;
		    }
		}
	      else if (macro && node->type == NT_MACRO_ARG)
		{
		  /* Found a parameter in the replacement text of a
		     #define.  Remove its name from the output.  */
		  pfile->out.cur = out_start;
		  save_replacement_text (pfile, macro, node->value.arg_index);
		  out = pfile->out.base;
		}
	      else if (lex_state == ls_hash)
		{
		  lex_state = ls_predicate;
		  continue;
		}
	      else if (pfile->state.in_expression
		       && node == pfile->spec_nodes.n_defined)
		{
		  lex_state = ls_defined;
		  continue;
		}
	    }
	  break;

	case '(':
	  if (quote == 0)
	    {
	      paren_depth++;
	      if (lex_state == ls_fun_open)
		{
		  if (recursive_macro (pfile, fmacro.node))
		    lex_state = ls_none;
		  else
		    {
		      lex_state = ls_fun_close;
		      paren_depth = 1;
		      out = pfile->out.base + fmacro.offset;
		      fmacro.args[0] = fmacro.offset;
		    }
		}
	      else if (lex_state == ls_predicate)
		lex_state = ls_answer;
	      else if (lex_state == ls_defined)
		lex_state = ls_defined_close;
	    }
	  break;

	case ',':
	  if (quote == 0 && lex_state == ls_fun_close && paren_depth == 1)
	    save_argument (&fmacro, out - pfile->out.base);
	  break;

	case ')':
	  if (quote == 0)
	    {
	      paren_depth--;
	      if (lex_state == ls_fun_close && paren_depth == 0)
		{
		  if (cpp_builtin_macro_p (fmacro.node))
		    {
		      /* Handle builtin function-like macros like
			 __has_attribute.  The already parsed arguments
			 are put into a buffer, which is then preprocessed
			 and the result is fed to _cpp_push_text_context
			 with disabled expansion, where the ISO preprocessor
			 parses it.  While in traditional preprocessing
			 macro arguments aren't immediately expanded, they in
			 the end are because the macro with replaced arguments
			 is preprocessed again.  For the builtin function-like
			 macros we need the argument immediately though,
			 if we don't preprocess them, they would behave
			 very differently from ISO preprocessor handling
			 of those builtin macros.  So, this handling is
			 more similar to traditional preprocessing of
			 #if directives, where we also keep preprocessing
			 until everything is expanded, and then feed the
			 result with disabled expansion to ISO preprocessor
			 for handling the directives.  */
		      lex_state = ls_none;
		      save_argument (&fmacro, out - pfile->out.base);
		      cpp_macro m;
		      memset (&m, '\0', sizeof (m));
		      m.paramc = fmacro.paramc;
		      if (_cpp_arguments_ok (pfile, &m, fmacro.node,
					     fmacro.argc))
			{
			  size_t len = fmacro.args[1] - fmacro.args[0];
			  uchar *buf;

			  /* Remove the macro's invocation from the
			     output, and push its replacement text.  */
			  pfile->out.cur = pfile->out.base + fmacro.offset;
			  CUR (context) = cur;
			  buf = _cpp_unaligned_alloc (pfile, len + 2);
			  buf[0] = '(';
			  memcpy (buf + 1, pfile->out.base + fmacro.args[0],
				  len);
			  buf[len + 1] = '\n';

			  const unsigned char *ctx_rlimit = RLIMIT (context);
			  const unsigned char *saved_cur = pfile->buffer->cur;
			  const unsigned char *saved_rlimit
			    = pfile->buffer->rlimit;
			  const unsigned char *saved_line_base
			    = pfile->buffer->line_base;
			  bool saved_need_line = pfile->buffer->need_line;
			  cpp_buffer *saved_overlaid_buffer
			    = pfile->overlaid_buffer;
			  pfile->buffer->cur = buf;
			  pfile->buffer->line_base = buf;
			  pfile->buffer->rlimit = buf + len + 1;
			  pfile->buffer->need_line = false;
			  pfile->overlaid_buffer = pfile->buffer;
			  bool saved_in_directive = pfile->state.in_directive;
			  pfile->state.in_directive = true;
			  cpp_context *saved_prev_context = context->prev;
			  context->prev = NULL;

			  _cpp_scan_out_logical_line (pfile, NULL, true);

			  pfile->state.in_directive = saved_in_directive;
			  check_output_buffer (pfile, 1);
			  *pfile->out.cur = '\n';
			  pfile->buffer->cur = pfile->out.base + fmacro.offset;
			  pfile->buffer->line_base = pfile->buffer->cur;
			  pfile->buffer->rlimit = pfile->out.cur;
			  CUR (context) = pfile->buffer->cur;
			  RLIMIT (context) = pfile->buffer->rlimit;

			  pfile->state.prevent_expansion++;
			  const uchar *text
			    = _cpp_builtin_macro_text (pfile, fmacro.node);
			  pfile->state.prevent_expansion--;

			  context->prev = saved_prev_context;
			  pfile->buffer->cur = saved_cur;
			  pfile->buffer->rlimit = saved_rlimit;
			  pfile->buffer->line_base = saved_line_base;
			  pfile->buffer->need_line = saved_need_line;
			  pfile->overlaid_buffer = saved_overlaid_buffer;
			  pfile->out.cur = pfile->out.base + fmacro.offset;
			  CUR (context) = cur;
			  RLIMIT (context) = ctx_rlimit;
			  len = ustrlen (text);
			  buf = _cpp_unaligned_alloc (pfile, len + 1);
			  memcpy (buf, text, len);
			  buf[len] = '\n';
			  text = buf;
			  _cpp_push_text_context (pfile, fmacro.node,
						  text, len);
			  goto new_context;
			}
		      break;
		    }

		  cpp_macro *m = fmacro.node->value.macro;

		  m->used = 1;
		  lex_state = ls_none;
		  save_argument (&fmacro, out - pfile->out.base);

		  /* A single zero-length argument is no argument.  */
		  if (fmacro.argc == 1
		      && m->paramc == 0
		      && out == pfile->out.base + fmacro.offset + 1)
		    fmacro.argc = 0;

		  if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc))
		    {
		      /* Remove the macro's invocation from the
			 output, and push its replacement text.  */
		      pfile->out.cur = pfile->out.base + fmacro.offset;
		      CUR (context) = cur;
		      replace_args_and_push (pfile, &fmacro);
		      goto new_context;
		    }
		}
	      else if (lex_state == ls_answer || lex_state == ls_defined_close)
		lex_state = ls_none;
	    }
	  break;

	case '#':
	  if (cur - 1 == start_of_input_line
	      /* A '#' from a macro doesn't start a directive.  */
	      && !pfile->context->prev
	      && !pfile->state.in_directive)
	    {
	      /* A directive.  With the way _cpp_handle_directive
		 currently works, we only want to call it if either we
		 know the directive is OK, or we want it to fail and
		 be removed from the output.  If we want it to be
		 passed through (the assembler case) then we must not
		 call _cpp_handle_directive.  */
	      pfile->out.cur = out;
	      cur = skip_whitespace (pfile, cur, true /* skip_comments */);
	      out = pfile->out.cur;

	      if (*cur == '\n')
		{
		  /* Null directive.  Ignore it and don't invalidate
		     the MI optimization.  */
		  pfile->buffer->need_line = true;
		  CPP_INCREMENT_LINE (pfile, 0);
		  result = false;
		  goto done;
		}
	      else
		{
		  bool do_it = false;

		  if (is_numstart (*cur)
		      && CPP_OPTION (pfile, lang) != CLK_ASM)
		    do_it = true;
		  else if (is_idstart (*cur))
		    /* Check whether we know this directive, but don't
		       advance.  */
		    do_it = lex_identifier (pfile, cur)->is_directive;

		  if (do_it || CPP_OPTION (pfile, lang) != CLK_ASM)
		    {
		      /* This is a kludge.  We want to have the ISO
			 preprocessor lex the next token.  */
		      pfile->buffer->cur = cur;
		      _cpp_handle_directive (pfile, false /* indented */);
		      result = false;
		      goto done;
		    }
		}
	    }

	  if (pfile->state.in_expression)
	    {
	      lex_state = ls_hash;
	      continue;
	    }
	  break;

	default:
	  break;
	}

      /* Non-whitespace disables MI optimization and stops treating
	 '<' as a quote in #include.  */
      header_ok = false;
      if (!pfile->state.in_directive)
	pfile->mi_valid = false;

      if (lex_state == ls_none)
	continue;

      /* Some of these transitions of state are syntax errors.  The
	 ISO preprocessor will issue errors later.  */
      if (lex_state == ls_fun_open)
	/* Missing '('.  */
	lex_state = ls_none;
      else if (lex_state == ls_hash
	       || lex_state == ls_predicate
	       || lex_state == ls_defined)
	lex_state = ls_none;

      /* ls_answer and ls_defined_close keep going until ')'.  */
    }

 done:
  if (fmacro.buff)
    _cpp_release_buff (pfile, fmacro.buff);

  if (lex_state == ls_fun_close)
    cpp_error_with_line (pfile, CPP_DL_ERROR, fmacro.line, 0,
			 "unterminated argument list invoking macro \"%s\"",
			 NODE_NAME (fmacro.node));
  return result;
}

/* Push a context holding the replacement text of the macro NODE on
   the context stack.  NODE is either object-like, or a function-like
   macro with no arguments.  */
static void
push_replacement_text (cpp_reader *pfile, cpp_hashnode *node)
{
  size_t len;
  const uchar *text;
  uchar *buf;

  if (cpp_builtin_macro_p (node))
    {
      text = _cpp_builtin_macro_text (pfile, node);
      len = ustrlen (text);
      buf = _cpp_unaligned_alloc (pfile, len + 1);
      memcpy (buf, text, len);
      buf[len] = '\n';
      text = buf;
    }
  else
    {
      cpp_macro *macro = node->value.macro;
      macro->used = 1;
      text = macro->exp.text;
      len = macro->count;
    }

  _cpp_push_text_context (pfile, node, text, len);
}

/* Returns TRUE if traditional macro recursion is detected.  */
static bool
recursive_macro (cpp_reader *pfile, cpp_hashnode *node)
{
  bool recursing = !!(node->flags & NODE_DISABLED);

  /* Object-like macros that are already expanding are necessarily
     recursive.

     However, it is possible to have traditional function-like macros
     that are not infinitely recursive but recurse to any given depth.
     Further, it is easy to construct examples that get ever longer
     until the point they stop recursing.  So there is no easy way to
     detect true recursion; instead we assume any expansion more than
     20 deep since the first invocation of this macro must be
     recursing.  */
  if (recursing && fun_like_macro (node))
    {
      size_t depth = 0;
      cpp_context *context = pfile->context;

      do
	{
	  depth++;
	  if (context->c.macro == node && depth > 20)
	    break;
	  context = context->prev;
	}
      while (context);
      recursing = context != NULL;
    }

  if (recursing)
    cpp_error (pfile, CPP_DL_ERROR,
	       "detected recursion whilst expanding macro \"%s\"",
	       NODE_NAME (node));

  return recursing;
}

/* Return the length of the replacement text of a function-like or
   object-like non-builtin macro.  */
size_t
_cpp_replacement_text_len (const cpp_macro *macro)
{
  size_t len;

  if (macro->fun_like && (macro->paramc != 0))
    {
      const uchar *exp;

      len = 0;
      for (exp = macro->exp.text;;)
	{
	  struct block *b = (struct block *) exp;

	  len += b->text_len;
	  if (b->arg_index == 0)
	    break;
	  len += NODE_LEN (macro->parm.params[b->arg_index - 1]);
	  exp += BLOCK_LEN (b->text_len);
	}
    }
  else
    len = macro->count;
  
  return len;
}

/* Copy the replacement text of MACRO to DEST, which must be of
   sufficient size.  It is not NUL-terminated.  The next character is
   returned.  */
uchar *
_cpp_copy_replacement_text (const cpp_macro *macro, uchar *dest)
{
  if (macro->fun_like && (macro->paramc != 0))
    {
      const uchar *exp;

      for (exp = macro->exp.text;;)
	{
	  struct block *b = (struct block *) exp;
	  cpp_hashnode *param;

	  memcpy (dest, b->text, b->text_len);
	  dest += b->text_len;
	  if (b->arg_index == 0)
	    break;
	  param = macro->parm.params[b->arg_index - 1];
	  memcpy (dest, NODE_NAME (param), NODE_LEN (param));
	  dest += NODE_LEN (param);
	  exp += BLOCK_LEN (b->text_len);
	}
    }
  else
    {
      memcpy (dest, macro->exp.text, macro->count);
      dest += macro->count;
    }

  return dest;
}

/* Push a context holding the replacement text of the macro NODE on
   the context stack.  NODE is either object-like, or a function-like
   macro with no arguments.  */
static void
replace_args_and_push (cpp_reader *pfile, struct fun_macro *fmacro)
{
  cpp_macro *macro = fmacro->node->value.macro;

  if (macro->paramc == 0)
    push_replacement_text (pfile, fmacro->node);
  else
    {
      const uchar *exp;
      uchar *p;
      _cpp_buff *buff;
      size_t len = 0;
      int cxtquote = 0;

      /* Get an estimate of the length of the argument-replaced text.
	 This is a worst case estimate, assuming that every replacement
	 text character needs quoting.  */
      for (exp = macro->exp.text;;)
	{
	  struct block *b = (struct block *) exp;

	  len += b->text_len;
	  if (b->arg_index == 0)
	    break;
	  len += 2 * (fmacro->args[b->arg_index]
		      - fmacro->args[b->arg_index - 1] - 1);
	  exp += BLOCK_LEN (b->text_len);
	}

      /* Allocate room for the expansion plus \n.  */
      buff = _cpp_get_buff (pfile, len + 1);

      /* Copy the expansion and replace arguments.  */
      /* Accumulate actual length, including quoting as necessary */
      p = BUFF_FRONT (buff);
      len = 0;
      for (exp = macro->exp.text;;)
	{
	  struct block *b = (struct block *) exp;
	  size_t arglen;
	  int argquote;
	  uchar *base;
	  uchar *in;

	  len += b->text_len;
	  /* Copy the non-argument text literally, keeping
	     track of whether matching quotes have been seen. */
	  for (arglen = b->text_len, in = b->text; arglen > 0; arglen--)
	    {
	      if (*in == '"')
		cxtquote = ! cxtquote;
	      *p++ = *in++;
	    }
	  /* Done if no more arguments */
	  if (b->arg_index == 0)
	    break;
	  arglen = (fmacro->args[b->arg_index]
		    - fmacro->args[b->arg_index - 1] - 1);
	  base = pfile->out.base + fmacro->args[b->arg_index - 1];
	  in = base;
#if 0
	  /* Skip leading whitespace in the text for the argument to
	     be substituted. To be compatible with gcc 2.95, we would
	     also need to trim trailing whitespace. Gcc 2.95 trims
	     leading and trailing whitespace, which may be a bug.  The
	     current gcc testsuite explicitly checks that this leading
	     and trailing whitespace in actual arguments is
	     preserved. */
	  while (arglen > 0 && is_space (*in))
	    {
	      in++;
	      arglen--;
	    }
#endif
	  for (argquote = 0; arglen > 0; arglen--)
	    {
	      if (cxtquote && *in == '"')
		{
		  if (in > base && *(in-1) != '\\')
		    argquote = ! argquote;
		  /* Always add backslash before double quote if argument
		     is expanded in a quoted context */
		  *p++ = '\\';
		  len++;
		}
	      else if (cxtquote && argquote && *in == '\\')
		{
		  /* Always add backslash before a backslash in an argument
		     that is expanded in a quoted context and also in the
		     range of a quoted context in the argument itself. */
		  *p++ = '\\';
		  len++;
		}
	      *p++ = *in++;
	      len++;
	    }
	  exp += BLOCK_LEN (b->text_len);
	}

      /* \n-terminate.  */
      *p = '\n';
      _cpp_push_text_context (pfile, fmacro->node, BUFF_FRONT (buff), len);

      /* So we free buffer allocation when macro is left.  */
      pfile->context->buff = buff;
    }
}

/* Read and record the parameters, if any, of a function-like macro
   definition.  Destroys pfile->out.cur.

   Returns true on success, false on failure (syntax error or a
   duplicate parameter).  On success, CUR (pfile->context) is just
   past the closing parenthesis.  */
static bool
scan_parameters (cpp_reader *pfile, unsigned *n_ptr)
{
  const uchar *cur = CUR (pfile->context) + 1;
  bool ok;

  unsigned nparms = 0;
  for (;;)
    {
      cur = skip_whitespace (pfile, cur, true /* skip_comments */);

      if (is_idstart (*cur))
	{
	  struct cpp_hashnode *id = lex_identifier (pfile, cur);
	  ok = false;
	  if (!_cpp_save_parameter (pfile, nparms, id, id))
	    break;
	  nparms++;
	  cur = skip_whitespace (pfile, CUR (pfile->context),
				 true /* skip_comments */);
	  if (*cur == ',')
	    {
	      cur++;
	      continue;
	    }
	  ok = (*cur == ')');
	  break;
	}

      ok = (*cur == ')' && !nparms);
      break;
    }

  *n_ptr = nparms;

  if (!ok)
    cpp_error (pfile, CPP_DL_ERROR, "syntax error in macro parameter list");

  CUR (pfile->context) = cur + (*cur == ')');

  return ok;
}

/* Save the text from pfile->out.base to pfile->out.cur as
   the replacement text for the current macro, followed by argument
   ARG_INDEX, with zero indicating the end of the replacement
   text.  */
static void
save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
		       unsigned int arg_index)
{
  size_t len = pfile->out.cur - pfile->out.base;
  uchar *exp;

  if (macro->paramc == 0)
    {
      /* Object-like and function-like macros without parameters
	 simply store their \n-terminated replacement text.  */
      exp = _cpp_unaligned_alloc (pfile, len + 1);
      memcpy (exp, pfile->out.base, len);
      exp[len] = '\n';
      macro->exp.text = exp;
      macro->count = len;
    }
  else
    {
      /* Store the text's length (unsigned int), the argument index
	 (unsigned short, base 1) and then the text.  */
      size_t blen = BLOCK_LEN (len);
      struct block *block;

      if (macro->count + blen > BUFF_ROOM (pfile->a_buff))
	_cpp_extend_buff (pfile, &pfile->a_buff, macro->count + blen);

      exp = BUFF_FRONT (pfile->a_buff);
      block = (struct block *) (exp + macro->count);
      macro->exp.text = exp;

      /* Write out the block information.  */
      block->text_len = len;
      block->arg_index = arg_index;
      memcpy (block->text, pfile->out.base, len);

      /* Lex the rest into the start of the output buffer.  */
      pfile->out.cur = pfile->out.base;

      macro->count += blen;

      /* If we've finished, commit the memory.  */
      if (arg_index == 0)
	BUFF_FRONT (pfile->a_buff) += macro->count;
    }
}

/* Analyze and save the replacement text of a macro.  Returns true on
   success.  */
cpp_macro *
_cpp_create_trad_definition (cpp_reader *pfile)
{
  const uchar *cur;
  uchar *limit;
  cpp_context *context = pfile->context;
  unsigned nparms = 0;
  int fun_like = 0;
  cpp_hashnode **params = NULL;

  /* The context has not been set up for command line defines, and CUR
     has not been updated for the macro name for in-file defines.  */
  pfile->out.cur = pfile->out.base;
  CUR (context) = pfile->buffer->cur;
  RLIMIT (context) = pfile->buffer->rlimit;
  check_output_buffer (pfile, RLIMIT (context) - CUR (context));

  /* Is this a function-like macro?  */
  if (* CUR (context) == '(')
    {
      fun_like = +1;
      if (scan_parameters (pfile, &nparms))
	params = (cpp_hashnode **)_cpp_commit_buff
	  (pfile, sizeof (cpp_hashnode *) * nparms);
      else
	fun_like = -1;
    }

  cpp_macro *macro = NULL;

  if (fun_like >= 0)
    {
      macro = _cpp_new_macro (pfile, cmk_traditional,
			      _cpp_aligned_alloc (pfile, sizeof (cpp_macro)));
      macro->parm.params = params;
      macro->paramc = nparms;
      macro->fun_like = fun_like != 0;
    }

  /* Skip leading whitespace in the replacement text.  */
  pfile->buffer->cur
    = skip_whitespace (pfile, CUR (context),
		       CPP_OPTION (pfile, discard_comments_in_macro_exp));

  pfile->state.prevent_expansion++;
  _cpp_scan_out_logical_line (pfile, macro, false);
  pfile->state.prevent_expansion--;

  _cpp_unsave_parameters (pfile, nparms);

  if (macro)
    {
      /* Skip trailing white space.  */
      cur = pfile->out.base;
      limit = pfile->out.cur;
      while (limit > cur && is_space (limit[-1]))
	limit--;
      pfile->out.cur = limit;
      save_replacement_text (pfile, macro, 0);
    }

  return macro;
}

/* Copy SRC of length LEN to DEST, but convert all contiguous
   whitespace to a single space, provided it is not in quotes.  The
   quote currently in effect is pointed to by PQUOTE, and is updated
   by the function.  Returns the number of bytes copied.  */
static size_t
canonicalize_text (uchar *dest, const uchar *src, size_t len, uchar *pquote)
{
  uchar *orig_dest = dest;
  uchar quote = *pquote;

  while (len)
    {
      if (is_space (*src) && !quote)
	{
	  do
	    src++, len--;
	  while (len && is_space (*src));
	  *dest++ = ' ';
	}
      else
	{
	  if (*src == '\'' || *src == '"')
	    {
	      if (!quote)
		quote = *src;
	      else if (quote == *src)
		quote = 0;
	    }
	  *dest++ = *src++, len--;
	}
    }

  *pquote = quote;
  return dest - orig_dest;
}

/* Returns true if MACRO1 and MACRO2 have expansions different other
   than in the form of their whitespace.  */
bool
_cpp_expansions_different_trad (const cpp_macro *macro1,
				const cpp_macro *macro2)
{
  uchar *p1 = XNEWVEC (uchar, macro1->count + macro2->count);
  uchar *p2 = p1 + macro1->count;
  uchar quote1 = 0, quote2 = 0;
  bool mismatch;
  size_t len1, len2;

  if (macro1->paramc > 0)
    {
      const uchar *exp1 = macro1->exp.text, *exp2 = macro2->exp.text;

      mismatch = true;
      for (;;)
	{
	  struct block *b1 = (struct block *) exp1;
	  struct block *b2 = (struct block *) exp2;

	  if (b1->arg_index != b2->arg_index)
	    break;

	  len1 = canonicalize_text (p1, b1->text, b1->text_len, &quote1);
	  len2 = canonicalize_text (p2, b2->text, b2->text_len, &quote2);
	  if (len1 != len2 || memcmp (p1, p2, len1))
	    break;
	  if (b1->arg_index == 0)
	    {
	      mismatch = false;
	      break;
	    }
	  exp1 += BLOCK_LEN (b1->text_len);
	  exp2 += BLOCK_LEN (b2->text_len);
	}
    }
  else
    {
      len1 = canonicalize_text (p1, macro1->exp.text, macro1->count, &quote1);
      len2 = canonicalize_text (p2, macro2->exp.text, macro2->count, &quote2);
      mismatch = (len1 != len2 || memcmp (p1, p2, len1));
    }

  free (p1);
  return mismatch;
}
