Text-CPP

 view release on metacpan or  search on metacpan

cpplib.c  view on Meta::CPAN

/* Wrapper struct directive for linemarkers.
   The origin is more or less true - the original K+R cpp
   did use this notation in its preprocessed output.  */
static const directive linemarker_dir =
{
  do_linemarker, U"#", 1, KANDR, IN_I
};

#define SEEN_EOL() (pfile->cur_token[-1].type == CPP_EOF)

/* Skip any remaining tokens in a directive.  */
static void
skip_rest_of_line (pfile)
     cpp_reader *pfile;
{
  /* Discard all stacked contexts.  */
  while (pfile->context->prev)
    _cpp_pop_context (pfile);

  /* Sweep up all tokens remaining on the line.  */
  if (! SEEN_EOL ())
    while (_cpp_lex_token (pfile)->type != CPP_EOF)
      ;
}

/* Ensure there are no stray tokens at the end of a directive.  */
static void
check_eol (pfile)
     cpp_reader *pfile;
{
  if (! SEEN_EOL () && _cpp_lex_token (pfile)->type != CPP_EOF)
    cpp_error (pfile, DL_PEDWARN, "extra tokens at end of #%s directive",
	       pfile->directive->name);
}

/* Called when entering a directive, _Pragma or command-line directive.  */
static void
start_directive (pfile)
     cpp_reader *pfile;
{
  /* Setup in-directive state.  */
  pfile->state.in_directive = 1;
  pfile->state.save_comments = 0;

  /* Some handlers need the position of the # for diagnostics.  */
  pfile->directive_line = pfile->line;
}

/* Called when leaving a directive, _Pragma or command-line directive.  */
static void
end_directive (pfile, skip_line)
     cpp_reader *pfile;
     int skip_line;
{
  if (CPP_OPTION (pfile, traditional))
    {
      /* Revert change of prepare_directive_trad.  */
      pfile->state.prevent_expansion--;

      if (pfile->directive != &dtable[T_DEFINE])
	_cpp_remove_overlay (pfile);
    }
  /* We don't skip for an assembler #.  */
  else if (skip_line)
    {
      skip_rest_of_line (pfile);
      if (!pfile->keep_tokens)
	{
	  pfile->cur_run = &pfile->base_run;
	  pfile->cur_token = pfile->base_run.base;
	}
    }

  /* Restore state.  */
  pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
  pfile->state.in_directive = 0;
  pfile->state.in_expression = 0;
  pfile->state.angled_headers = 0;
  pfile->directive = 0;
}

/* Prepare to handle the directive in pfile->directive.  */
static void
prepare_directive_trad (pfile)
     cpp_reader *pfile;
{
  if (pfile->directive != &dtable[T_DEFINE])
    {
      bool no_expand = (pfile->directive
			&& ! (pfile->directive->flags & EXPAND));
      bool was_skipping = pfile->state.skipping;

      pfile->state.skipping = false;
      pfile->state.in_expression = (pfile->directive == &dtable[T_IF]
				    || pfile->directive == &dtable[T_ELIF]);
      if (no_expand)
	pfile->state.prevent_expansion++;
      _cpp_read_logical_line_trad (pfile);
      if (no_expand)
	pfile->state.prevent_expansion--;
      pfile->state.skipping = was_skipping;
      _cpp_overlay_buffer (pfile, pfile->out.base,
			   pfile->out.cur - pfile->out.base);
    }

  /* Stop ISO C from expanding anything.  */
  pfile->state.prevent_expansion++;
}

/* Output diagnostics for a directive DIR.  INDENTED is nonzero if
   the '#' was indented.  */
static void
directive_diagnostics (pfile, dir, indented)
     cpp_reader *pfile;
     const directive *dir;
     int indented;
{
  /* Issue -pedantic warnings for extensions.  */
  if (CPP_PEDANTIC (pfile)
      && ! pfile->state.skipping
      && dir->origin == EXTENSION)
    cpp_error (pfile, DL_PEDWARN, "#%s is a GCC extension", dir->name);

  /* Traditionally, a directive is ignored unless its # is in
     column 1.  Therefore in code intended to work with K+R
     compilers, directives added by C89 must have their #
     indented, and directives present in traditional C must not.
     This is true even of directives in skipped conditional
     blocks.  #elif cannot be used at all.  */
  if (CPP_WTRADITIONAL (pfile))
    {
      if (dir == &dtable[T_ELIF])
	cpp_error (pfile, DL_WARNING,
		   "suggest not using #elif in traditional C");
      else if (indented && dir->origin == KANDR)
	cpp_error (pfile, DL_WARNING,
		   "traditional C ignores #%s with the # indented",
		   dir->name);
      else if (!indented && dir->origin != KANDR)
	cpp_error (pfile, DL_WARNING,
		   "suggest hiding #%s from traditional C with an indented #",
		   dir->name);
    }
}

/* Check if we have a known directive.  INDENTED is nonzero if the
   '#' of the directive was indented.  This function is in this file
   to save unnecessarily exporting dtable etc. to cpplex.c.  Returns
   nonzero if the line of tokens has been handled, zero if we should
   continue processing the line.  */
int
_cpp_handle_directive (pfile, indented)
     cpp_reader *pfile;
     int indented;
{
  const directive *dir = 0;
  const cpp_token *dname;
  bool was_parsing_args = pfile->state.parsing_args;
  int skip = 1;

  if (was_parsing_args)
    {



( run in 0.788 second using v1.01-cache-2.11-cpan-39bf76dae61 )