示例#1
0
/* For preprocessed files, if the first tokens are of the form # NUM.
   handle the directive so we know the original file name.  This will
   generate file_change callbacks, which the front ends must handle
   appropriately given their state of initialization.  */
static void
read_original_filename (cpp_reader *pfile)
{
  const cpp_token *token, *token1;

  /* Lex ahead; if the first tokens are of the form # NUM, then
     process the directive, otherwise back up.  */
  token = _cpp_lex_direct (pfile);
  if (token->type == CPP_HASH)
    {
      pfile->state.in_directive = 1;
      token1 = _cpp_lex_direct (pfile);
      _cpp_backup_tokens (pfile, 1);
      pfile->state.in_directive = 0;

      /* If it's a #line directive, handle it.  */
      if (token1->type == CPP_NUMBER
	  && _cpp_handle_directive (pfile, token->flags & PREV_WHITE))
	{
	  read_original_directory (pfile);
	  return;
	}
    }

  /* Backup as if nothing happened.  */
  _cpp_backup_tokens (pfile, 1);
}
示例#2
0
/* For preprocessed files, if the tokens following the first filename
   line is of the form # <line> "/path/name//", handle the
   directive so we know the original current directory.  */
static void
read_original_directory (cpp_reader *pfile)
{
  const cpp_token *hash, *token;

  /* Lex ahead; if the first tokens are of the form # NUM, then
     process the directive, otherwise back up.  */
  hash = _cpp_lex_direct (pfile);
  if (hash->type != CPP_HASH)
    {
      _cpp_backup_tokens (pfile, 1);
      return;
    }

  token = _cpp_lex_direct (pfile);

  if (token->type != CPP_NUMBER)
    {
      _cpp_backup_tokens (pfile, 2);
      return;
    }

  token = _cpp_lex_direct (pfile);

  if (token->type != CPP_STRING
      || ! (token->val.str.len >= 5
	    && IS_DIR_SEPARATOR (token->val.str.text[token->val.str.len-2])
	    && IS_DIR_SEPARATOR (token->val.str.text[token->val.str.len-3])))
    {
      _cpp_backup_tokens (pfile, 3);
      return;
    }

  if (pfile->cb.dir_change)
    {
      char *debugdir = (char *) alloca (token->val.str.len - 3);

      memcpy (debugdir, (const char *) token->val.str.text + 1,
	      token->val.str.len - 4);
      debugdir[token->val.str.len - 4] = '\0';

      pfile->cb.dir_change (pfile, debugdir);
    }      
}
示例#3
0
文件: cpplex.c 项目: Fokycnuk/gcc
/* Lex a token into RESULT (external interface).  Takes care of issues
   like directive handling, token lookahead, multiple include
   optimization and skipping.  */
const cpp_token *
_cpp_lex_token (cpp_reader *pfile)
{
  cpp_token *result;

  for (;;)
    {
      if (pfile->cur_token == pfile->cur_run->limit)
	{
	  pfile->cur_run = next_tokenrun (pfile->cur_run);
	  pfile->cur_token = pfile->cur_run->base;
	}

      if (pfile->lookaheads)
	{
	  pfile->lookaheads--;
	  result = pfile->cur_token++;
	}
      else
	result = _cpp_lex_direct (pfile);

      if (result->flags & BOL)
	{
	  /* Is this a directive.  If _cpp_handle_directive returns
	     false, it is an assembler #.  */
	  if (result->type == CPP_HASH
	      /* 6.10.3 p 11: Directives in a list of macro arguments
		 gives undefined behavior.  This implementation
		 handles the directive as normal.  */
	      && pfile->state.parsing_args != 1
	      && _cpp_handle_directive (pfile, result->flags & PREV_WHITE))
	    continue;
	  if (pfile->cb.line_change && !pfile->state.skipping)
	    pfile->cb.line_change (pfile, result, pfile->state.parsing_args);
	}

      /* We don't skip tokens in directives.  */
      if (pfile->state.in_directive)
	break;

      /* Outside a directive, invalidate controlling macros.  At file
	 EOF, _cpp_lex_direct takes care of popping the buffer, so we never
	 get here and MI optimization works.  */
      pfile->mi_valid = false;

      if (!pfile->state.skipping || result->type == CPP_EOF)
	break;
    }

  return result;
}