/* Helper function for cb_line_change and scan_translation_unit.  */
static void
do_line_change (cpp_reader *pfile, const cpp_token *token,
		source_location src_loc, int parsing_args)
{
  if (define_queue || undef_queue)
    dump_queued_macros (pfile);

  if (token->type == CPP_EOF || parsing_args)
    return;

  maybe_print_line (src_loc);
  print.prev = 0;
  print.source = 0;

  /* Supply enough spaces to put this token in its original column,
     one space per column greater than 2, since scan_translation_unit
     will provide a space if PREV_WHITE.  Don't bother trying to
     reconstruct tabs; we can't get it right in general, and nothing
     ought to care.  Some things do care; the fault lies with them.  */
  if (!CPP_OPTION (pfile, traditional))
    {
      const struct line_map *map = linemap_lookup (line_table, src_loc);
      int spaces = SOURCE_COLUMN (map, src_loc) - 2;
      print.printed = 1;

      while (-- spaces >= 0)
	putc (' ', print.outf);
    }
}
Ejemplo n.º 2
0
/* Called when a line of output is started.  TOKEN is the first token
   of the line, and at end of file will be CPP_EOF.  */
static void
cb_line_change (cpp_reader *pfile, const cpp_token *token,
                int parsing_args)
{
    if (token->type == CPP_EOF || parsing_args)
        return;

    maybe_print_line (print.map, token->line);
    print.prev = 0;
    print.source = 0;

    /* Supply enough spaces to put this token in its original column,
       one space per column greater than 2, since scan_translation_unit
       will provide a space if PREV_WHITE.  Don't bother trying to
       reconstruct tabs; we can't get it right in general, and nothing
       ought to care.  Some things do care; the fault lies with them.  */
    if (!CPP_OPTION (pfile, traditional))
    {
        print.printed = 1;
        if (token->col > 2)
        {
            unsigned int spaces = token->col - 2;

            while (spaces--)
                putc (' ', print.outf);
        }
    }
}
/* Writes out a traditionally preprocessed file.  */
static void
scan_translation_unit_trad (cpp_reader *pfile)
{
  while (_cpp_read_logical_line_trad (pfile))
    {
      size_t len = pfile->out.cur - pfile->out.base;
      maybe_print_line (pfile->out.first_line);
      fwrite (pfile->out.base, 1, len, print.outf);
      print.printed = 1;
      if (!CPP_OPTION (pfile, discard_comments))
	account_for_newlines (pfile->out.base, len);
    }
}
/* Writes out the preprocessed file, handling spacing and paste
   avoidance issues.  */
static void
scan_translation_unit (cpp_reader *pfile)
{
  bool avoid_paste = false;
  bool do_line_adjustments
    = cpp_get_options (parse_in)->lang != CLK_ASM
      && !flag_no_line_commands;
  bool in_pragma = false;

  print.source = NULL;
  for (;;)
    {
      source_location loc;
      const cpp_token *token = cpp_get_token_with_location (pfile, &loc);

      if (token->type == CPP_PADDING)
	{
	  avoid_paste = true;
	  if (print.source == NULL
	      || (!(print.source->flags & PREV_WHITE)
		  && token->val.source == NULL))
	    print.source = token->val.source;
	  continue;
	}

      if (token->type == CPP_EOF)
	break;

      /* Subtle logic to output a space if and only if necessary.  */
      if (avoid_paste)
	{
	  const struct line_map *map
	    = linemap_lookup (line_table, loc);
	  int src_line = SOURCE_LINE (map, loc);

	  if (print.source == NULL)
	    print.source = token;

	  if (src_line != print.src_line
	      && do_line_adjustments
	      && !in_pragma)
	    {
	      do_line_change (pfile, token, loc, false);
	      putc (' ', print.outf);
	    }
	  else if (print.source->flags & PREV_WHITE
		   || (print.prev
		       && cpp_avoid_paste (pfile, print.prev, token))
		   || (print.prev == NULL && token->type == CPP_HASH))
	    putc (' ', print.outf);
	}
      else if (token->flags & PREV_WHITE)
	{
	  const struct line_map *map
	    = linemap_lookup (line_table, loc);
	  int src_line = SOURCE_LINE (map, loc);

	  if (src_line != print.src_line
	      && do_line_adjustments
	      && !in_pragma)
	    do_line_change (pfile, token, loc, false);
	  putc (' ', print.outf);
	}

      avoid_paste = false;
      print.source = NULL;
      print.prev = token;
      if (token->type == CPP_PRAGMA)
	{
	  const char *space;
	  const char *name;

	  maybe_print_line (token->src_loc);
	  fputs ("#pragma ", print.outf);
	  c_pp_lookup_pragma (token->val.pragma, &space, &name);
	  if (space)
	    fprintf (print.outf, "%s %s", space, name);
	  else
	    fprintf (print.outf, "%s", name);
	  print.printed = 1;
	  in_pragma = true;
	}
      else if (token->type == CPP_PRAGMA_EOL)
	{
	  maybe_print_line (token->src_loc);
	  in_pragma = false;
	}
      else
	cpp_output_token (token, print.outf);

      if (token->type == CPP_COMMENT)
	account_for_newlines (token->val.str.text, token->val.str.len);
    }
}
Ejemplo n.º 5
0
/* Writes out the preprocessed file, handling spacing and paste
   avoidance issues.  */
static void
scan_translation_unit (cpp_reader *pfile)
{
  bool avoid_paste = false;
  bool do_line_adjustments
    = cpp_get_options (parse_in)->lang != CLK_ASM
      && !flag_no_line_commands;
  bool in_pragma = false;

  print.source = NULL;
  for (;;)
    {
      source_location loc;
      const cpp_token *token = cpp_get_token_with_location (pfile, &loc);

      if (token->type == CPP_PADDING)
	{
	  avoid_paste = true;
	  if (print.source == NULL
	      || (!(print.source->flags & PREV_WHITE)
		  && token->val.source == NULL))
	    print.source = token->val.source;
	  continue;
	}

      if (token->type == CPP_EOF)
	break;

      /* Subtle logic to output a space if and only if necessary.  */
      if (avoid_paste)
	{
	  int src_line = LOCATION_LINE (loc);

	  if (print.source == NULL)
	    print.source = token;

	  if (src_line != print.src_line
	      && do_line_adjustments
	      && !in_pragma)
	    {
	      do_line_change (pfile, token, loc, false);
	      putc (' ', print.outf);
	    }
	  else if (print.source->flags & PREV_WHITE
		   || (print.prev
		       && cpp_avoid_paste (pfile, print.prev, token))
		   || (print.prev == NULL && token->type == CPP_HASH))
	    putc (' ', print.outf);
	}
      else if (token->flags & PREV_WHITE)
	{
	  int src_line = LOCATION_LINE (loc);

	  if (src_line != print.src_line
	      && do_line_adjustments
	      && !in_pragma)
	    do_line_change (pfile, token, loc, false);
	  putc (' ', print.outf);
	}

      avoid_paste = false;
      print.source = NULL;
      print.prev = token;
      if (token->type == CPP_PRAGMA)
	{
	  const char *space;
	  const char *name;

	  maybe_print_line (token->src_loc);
	  fputs ("#pragma ", print.outf);
	  c_pp_lookup_pragma (token->val.pragma, &space, &name);
	  if (space)
	    fprintf (print.outf, "%s %s", space, name);
	  else
	    fprintf (print.outf, "%s", name);
	  print.printed = 1;
	  in_pragma = true;
	}
      else if (token->type == CPP_PRAGMA_EOL)
	{
	  maybe_print_line (token->src_loc);
	  in_pragma = false;
	}
      else
	{
	  if (cpp_get_options (parse_in)->debug)
	      linemap_dump_location (line_table, token->src_loc,
				     print.outf);
	  cpp_output_token (token, print.outf);
	}

      /* CPP_COMMENT tokens and raw-string literal tokens can
	 have embedded new-line characters.  Rather than enumerating
	 all the possible token types just check if token uses
	 val.str union member.  */
      if (cpp_token_val_index (token) == CPP_TOKEN_FLD_STR)
	account_for_newlines (token->val.str.text, token->val.str.len);
    }
}