/* Copyright (C) 2008-2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "gfortran.h"
#include "diagnostic.h"


#include "toplev.h"

#include "../../libcpp/internal.h"
#include "cpp.h"
#include "incpath.h"
#include "cppbuiltin.h"
#include "mkdeps.h"

#ifndef TARGET_SYSTEM_ROOT
# define TARGET_SYSTEM_ROOT NULL
#endif

#ifndef TARGET_CPU_CPP_BUILTINS
# define TARGET_CPU_CPP_BUILTINS()
#endif

#ifndef TARGET_OS_CPP_BUILTINS
# define TARGET_OS_CPP_BUILTINS()
#endif

#ifndef TARGET_OBJFMT_CPP_BUILTINS
# define TARGET_OBJFMT_CPP_BUILTINS()
#endif


/* Holds switches parsed by gfc_cpp_handle_option (), but whose
   handling is deferred to gfc_cpp_init ().  */
typedef struct
{
    enum opt_code code;
    const char *arg;
}
gfc_cpp_deferred_opt_t;


/* Defined and undefined macros being queued for output with -dU at
   the next newline.  */
typedef struct gfc_cpp_macro_queue
{
  struct gfc_cpp_macro_queue *next;	/* Next macro in the list.  */
  char *macro;				/* The name of the macro if not
					   defined, the full definition if
					   defined.  */
} gfc_cpp_macro_queue;
static gfc_cpp_macro_queue *cpp_define_queue, *cpp_undefine_queue;

struct gfc_cpp_option_data
{
  /* Argument of -cpp, implied by SPEC;
     if NULL, preprocessing disabled.  */
  const char *temporary_filename;

  const char *output_filename;          /* -o <arg>  */
  int preprocess_only;                  /* -E  */
  int discard_comments;                 /* -C  */
  int discard_comments_in_macro_exp;    /* -CC  */
  int print_include_names;              /* -H  */
  int no_line_commands;                 /* -P  */
  char dump_macros;                     /* -d[DMNU]  */
  int dump_includes;                    /* -dI  */
  int working_directory;                /* -fworking-directory  */
  int no_predefined;                    /* -undef */
  int standard_include_paths;           /* -nostdinc */
  int verbose;                          /* -v */
  int deps;                             /* -M */
  int deps_skip_system;                 /* -MM */
  const char *deps_filename;            /* -M[M]D */
  const char *deps_filename_user;       /* -MF <arg> */
  int deps_missing_are_generated;       /* -MG */
  int deps_phony;                       /* -MP */
  int warn_date_time;                   /* -Wdate-time */

  const char *multilib;                 /* -imultilib <dir>  */
  const char *prefix;                   /* -iprefix <dir>  */
  const char *sysroot;                  /* -isysroot <dir>  */

  /* Options whose handling needs to be deferred until the
     appropriate cpp-objects are created:
      -A predicate=answer
      -D <macro>[=<val>]
      -U <macro>  */
  gfc_cpp_deferred_opt_t *deferred_opt;
  int deferred_opt_count;
}
gfc_cpp_option;

/* Structures used with libcpp:  */
static cpp_options *cpp_option = NULL;
static cpp_reader *cpp_in = NULL;

/* Encapsulates state used to convert a stream of cpp-tokens into
   a text file.  */
static struct
{
  FILE *outf;			/* Stream to write to.  */
  const cpp_token *prev;	/* Previous token.  */
  const cpp_token *source;	/* Source token for spacing.  */
  int src_line;			/* Line number currently being written.  */
  unsigned char printed;	/* Nonzero if something output at line.  */
  bool first_time;		/* cb_file_change hasn't been called yet.  */
} print;

/* General output routines.  */
static void scan_translation_unit (cpp_reader *);
static void scan_translation_unit_trad (cpp_reader *);

/* Callback routines for the parser. Most of these are active only
   in specific modes.  */
static void cb_file_change (cpp_reader *, const line_map_ordinary *);
static void cb_line_change (cpp_reader *, const cpp_token *, int);
static void cb_define (cpp_reader *, location_t, cpp_hashnode *);
static void cb_undef (cpp_reader *, location_t, cpp_hashnode *);
static void cb_def_pragma (cpp_reader *, location_t);
static void cb_include (cpp_reader *, location_t, const unsigned char *,
			const char *, int, const cpp_token **);
static void cb_ident (cpp_reader *, location_t, const cpp_string *);
static void cb_used_define (cpp_reader *, location_t, cpp_hashnode *);
static void cb_used_undef (cpp_reader *, location_t, cpp_hashnode *);
static bool cb_cpp_diagnostic (cpp_reader *, enum cpp_diagnostic_level,
			       enum cpp_warning_reason, rich_location *,
			       const char *, va_list *)
     ATTRIBUTE_GCC_DIAG(5,0);
void pp_dir_change (cpp_reader *, const char *);

static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
static void dump_queued_macros (cpp_reader *);


static void
cpp_define_builtins (cpp_reader *pfile)
{
  /* Initialize CPP built-ins; '1' corresponds to 'flag_hosted'
     in C, defines __STDC_HOSTED__?!  */
  cpp_init_builtins (pfile, 0);

  /* Initialize GFORTRAN specific builtins.
     These are documented.  */
  define_language_independent_builtin_macros (pfile);
  cpp_define (pfile, "__GFORTRAN__=1");
  cpp_define (pfile, "_LANGUAGE_FORTRAN=1");

  if (flag_openacc)
    cpp_define (pfile, "_OPENACC=201711");

  if (flag_openmp)
    cpp_define (pfile, "_OPENMP=201511");

  /* The defines below are necessary for the TARGET_* macros.

     FIXME:  Note that builtin_define_std() actually is a function
     in c-cppbuiltin.c which uses flags undefined for Fortran.
     Let's skip this for now. If needed, one needs to look into it
     once more.  */

# define builtin_define(TXT) cpp_define (pfile, TXT)
# define builtin_define_std(TXT)
# define builtin_assert(TXT) cpp_assert (pfile, TXT)

  /* FIXME: Pandora's Box
    Using the macros below results in multiple breakages:
     - mingw will fail to compile this file as dependent macros
       assume to be used in c-cppbuiltin.c only. Further, they use
       flags only valid/defined in C (same as noted above).
       [config/i386/mingw32.h, config/i386/cygming.h]
     - other platforms (not as popular) break similarly
       [grep for 'builtin_define_with_int_value' in gcc/config/]

  TARGET_CPU_CPP_BUILTINS ();
  TARGET_OS_CPP_BUILTINS ();
  TARGET_OBJFMT_CPP_BUILTINS (); */

#undef builtin_define
#undef builtin_define_std
#undef builtin_assert
}

bool
gfc_cpp_enabled (void)
{
  return gfc_cpp_option.temporary_filename != NULL;
}

bool
gfc_cpp_preprocess_only (void)
{
  return gfc_cpp_option.preprocess_only;
}

bool
gfc_cpp_makedep (void)
{
  return gfc_cpp_option.deps;
}

void
gfc_cpp_add_dep (const char *name, bool system)
{
  if (!gfc_cpp_option.deps_skip_system || !system)
    if (mkdeps *deps = cpp_get_deps (cpp_in))
      deps_add_dep (deps, name);
}

void
gfc_cpp_add_target (const char *name)
{
  if (mkdeps *deps = cpp_get_deps (cpp_in))
    deps_add_target (deps, name, 0);
}


const char *
gfc_cpp_temporary_file (void)
{
  return gfc_cpp_option.temporary_filename;
}

void
gfc_cpp_init_options (unsigned int decoded_options_count,
		      struct cl_decoded_option *decoded_options ATTRIBUTE_UNUSED)
{
  /* Do not create any objects from libcpp here. If no
     preprocessing is requested, this would be wasted
     time and effort.

     See gfc_cpp_post_options() instead.  */

  gfc_cpp_option.temporary_filename = NULL;
  gfc_cpp_option.output_filename = NULL;
  gfc_cpp_option.preprocess_only = 0;
  gfc_cpp_option.discard_comments = 1;
  gfc_cpp_option.discard_comments_in_macro_exp = 1;
  gfc_cpp_option.print_include_names = 0;
  gfc_cpp_option.no_line_commands = 0;
  gfc_cpp_option.dump_macros = '\0';
  gfc_cpp_option.dump_includes = 0;
  gfc_cpp_option.working_directory = -1;
  gfc_cpp_option.no_predefined = 0;
  gfc_cpp_option.standard_include_paths = 1;
  gfc_cpp_option.verbose = 0;
  gfc_cpp_option.warn_date_time = 0;
  gfc_cpp_option.deps = 0;
  gfc_cpp_option.deps_skip_system = 0;
  gfc_cpp_option.deps_phony = 0;
  gfc_cpp_option.deps_missing_are_generated = 0;
  gfc_cpp_option.deps_filename = NULL;
  gfc_cpp_option.deps_filename_user = NULL;

  gfc_cpp_option.multilib = NULL;
  gfc_cpp_option.prefix = NULL;
  gfc_cpp_option.sysroot = TARGET_SYSTEM_ROOT;

  gfc_cpp_option.deferred_opt = XNEWVEC (gfc_cpp_deferred_opt_t,
					 decoded_options_count);
  gfc_cpp_option.deferred_opt_count = 0;
}

int
gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED)
{
  int result = 1;
  enum opt_code code = (enum opt_code) scode;

  switch (code)
  {
    default:
      result = 0;
      break;

    case OPT_cpp_:
      gfc_cpp_option.temporary_filename = arg;
      break;

    case OPT_nocpp:
      gfc_cpp_option.temporary_filename = 0L;
      break;

    case OPT_d:
      for ( ; *arg; ++arg)
        switch (*arg)
	{
	  case 'D':
	  case 'M':
	  case 'N':
	  case 'U':
	    gfc_cpp_option.dump_macros = *arg;
	    break;

	  case 'I':
	    gfc_cpp_option.dump_includes = 1;
	    break;
	}
      break;

    case OPT_fworking_directory:
      gfc_cpp_option.working_directory = value;
      break;

    case OPT_idirafter:
      gfc_cpp_add_include_path_after (xstrdup(arg), true);
      break;

    case OPT_imultilib:
      gfc_cpp_option.multilib = arg;
      break;

    case OPT_iprefix:
      gfc_cpp_option.prefix = arg;
      break;

    case OPT_isysroot:
      gfc_cpp_option.sysroot = arg;
      break;

    case OPT_iquote:
    case OPT_isystem:
      gfc_cpp_add_include_path (xstrdup(arg), true);
      break;

    case OPT_nostdinc:
      gfc_cpp_option.standard_include_paths = value;
      break;

    case OPT_o:
      if (!gfc_cpp_option.output_filename)
	gfc_cpp_option.output_filename = arg;
      else
	gfc_fatal_error ("output filename specified twice");
      break;

    case OPT_undef:
      gfc_cpp_option.no_predefined = value;
      break;

    case OPT_v:
      gfc_cpp_option.verbose = value;
      break;

    case OPT_Wdate_time:
      gfc_cpp_option.warn_date_time = value;
      break;

    case OPT_A:
    case OPT_D:
    case OPT_U:
      gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].code = code;
      gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].arg = arg;
      gfc_cpp_option.deferred_opt_count++;
      break;

    case OPT_C:
      gfc_cpp_option.discard_comments = 0;
      break;

    case OPT_CC:
      gfc_cpp_option.discard_comments = 0;
      gfc_cpp_option.discard_comments_in_macro_exp = 0;
      break;

    case OPT_E:
      gfc_cpp_option.preprocess_only = 1;
      break;

    case OPT_H:
      gfc_cpp_option.print_include_names = 1;
      break;

    case OPT_MM:
      gfc_cpp_option.deps_skip_system = 1;
      /* fall through */

    case OPT_M:
      gfc_cpp_option.deps = 1;
      break;

    case OPT_MMD:
      gfc_cpp_option.deps_skip_system = 1;
      /* fall through */

    case OPT_MD:
      gfc_cpp_option.deps = 1;
      gfc_cpp_option.deps_filename = arg;
      break;

    case OPT_MF:
      /* If specified multiple times, last one wins.  */
      gfc_cpp_option.deps_filename_user = arg;
      break;

    case OPT_MG:
      gfc_cpp_option.deps_missing_are_generated = 1;
      break;

    case OPT_MP:
      gfc_cpp_option.deps_phony = 1;
      break;

    case OPT_MQ:
    case OPT_MT:
      gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].code = code;
      gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].arg = arg;
      gfc_cpp_option.deferred_opt_count++;
      break;

    case OPT_P:
      gfc_cpp_option.no_line_commands = 1;
      break;
  }

  return result;
}


void
gfc_cpp_post_options (void)
{
  /* Any preprocessing-related option without '-cpp' is considered
     an error.  */
  if (!gfc_cpp_enabled ()
      && (gfc_cpp_preprocess_only ()
	  || gfc_cpp_makedep ()
	  || !gfc_cpp_option.discard_comments
	  || !gfc_cpp_option.discard_comments_in_macro_exp
	  || gfc_cpp_option.print_include_names
	  || gfc_cpp_option.no_line_commands
	  || gfc_cpp_option.dump_macros
	  || gfc_cpp_option.dump_includes))
    gfc_fatal_error ("To enable preprocessing, use %<-cpp%>");

  if (!gfc_cpp_enabled ())
    return;

  cpp_in = cpp_create_reader (CLK_GNUC89, NULL, line_table);
  gcc_assert (cpp_in);

  /* The cpp_options-structure defines far more flags than those set here.
     If any other is implemented, see c-opt.c (sanitize_cpp_opts) for
     inter-option dependencies that may need to be enforced.  */
  cpp_option = cpp_get_options (cpp_in);
  gcc_assert (cpp_option);

  /* TODO: allow non-traditional modes, e.g. by -cpp-std=...?  */
  cpp_option->traditional = 1;
  cpp_option->cplusplus_comments = 0;

  cpp_option->cpp_pedantic = pedantic;

  cpp_option->dollars_in_ident = flag_dollar_ok;
  cpp_option->discard_comments = gfc_cpp_option.discard_comments;
  cpp_option->discard_comments_in_macro_exp = gfc_cpp_option.discard_comments_in_macro_exp;
  cpp_option->print_include_names = gfc_cpp_option.print_include_names;
  cpp_option->preprocessed = gfc_option.flag_preprocessed;
  cpp_option->warn_date_time = gfc_cpp_option.warn_date_time;

  if (gfc_cpp_makedep ())
    {
      cpp_option->deps.style = DEPS_USER;
      cpp_option->deps.phony_targets = gfc_cpp_option.deps_phony;
      cpp_option->deps.missing_files = gfc_cpp_option.deps_missing_are_generated;

      /* -MF <arg> overrides -M[M]D.  */
      if (gfc_cpp_option.deps_filename_user)
	gfc_cpp_option.deps_filename = gfc_cpp_option.deps_filename_user;
  }

  if (gfc_cpp_option.working_directory == -1)
    gfc_cpp_option.working_directory = (debug_info_level != DINFO_LEVEL_NONE);

  cpp_post_options (cpp_in);


  /* Let diagnostics infrastructure know how to convert input files the same
     way libcpp will do it, namely, with no charset conversion but with
     skipping of a UTF-8 BOM if present.  */
  diagnostic_initialize_input_context (global_dc, nullptr, true);

  gfc_cpp_register_include_paths ();
}


void
gfc_cpp_init_0 (void)
{
  struct cpp_callbacks *cb;

  cb = cpp_get_callbacks (cpp_in);
  cb->file_change = cb_file_change;
  cb->line_change = cb_line_change;
  cb->ident = cb_ident;
  cb->def_pragma = cb_def_pragma;
  cb->diagnostic = cb_cpp_diagnostic;

  if (gfc_cpp_option.dump_includes)
    cb->include = cb_include;

  if ((gfc_cpp_option.dump_macros == 'D')
      || (gfc_cpp_option.dump_macros == 'N'))
    {
      cb->define = cb_define;
      cb->undef  = cb_undef;
    }

  if (gfc_cpp_option.dump_macros == 'U')
    {
      cb->before_define = dump_queued_macros;
      cb->used_define = cb_used_define;
      cb->used_undef = cb_used_undef;
    }

  /* Initialize the print structure.  Setting print.src_line to -1 here is
     a trick to guarantee that the first token of the file will cause
     a linemarker to be output by maybe_print_line.  */
  print.src_line = -1;
  print.printed = 0;
  print.prev = 0;
  print.first_time = 1;

  if (gfc_cpp_preprocess_only ())
    {
      if (gfc_cpp_option.output_filename)
	{
	  /* This needs cheating: with "-E -o <file>", the user wants the
	     preprocessed output in <file>. However, if nothing is done
	     about it <file> is also used for assembler output. Hence, it
	     is necessary to redirect assembler output (actually nothing
	     as -E implies -fsyntax-only) to another file, otherwise the
	     output from preprocessing is lost.  */
	  asm_file_name = gfc_cpp_option.temporary_filename;

	  print.outf = fopen (gfc_cpp_option.output_filename, "w");
	  if (print.outf == NULL)
	    gfc_fatal_error ("opening output file %qs: %s",
			     gfc_cpp_option.output_filename,
			     xstrerror (errno));
	}
      else
	print.outf = stdout;
    }
  else
    {
      print.outf = fopen (gfc_cpp_option.temporary_filename, "w");
      if (print.outf == NULL)
	gfc_fatal_error ("opening output file %qs: %s",
			 gfc_cpp_option.temporary_filename, xstrerror (errno));
    }

  gcc_assert(cpp_in);
  if (!cpp_read_main_file (cpp_in, gfc_source_file))
    errorcount++;
}

void
gfc_cpp_init (void)
{
  int i;

  if (gfc_option.flag_preprocessed)
    return;

  cpp_change_file (cpp_in, LC_RENAME, _("<built-in>"));
  if (!gfc_cpp_option.no_predefined)
    {
      /* Make sure all of the builtins about to be declared have
	BUILTINS_LOCATION has their location_t.  */
      cpp_force_token_locations (cpp_in, BUILTINS_LOCATION);

      cpp_define_builtins (cpp_in);

      cpp_stop_forcing_token_locations (cpp_in);
    }

  /* Handle deferred options from command-line.  */
  cpp_change_file (cpp_in, LC_RENAME, _("<command-line>"));

  for (i = 0; i < gfc_cpp_option.deferred_opt_count; i++)
    {
      gfc_cpp_deferred_opt_t *opt = &gfc_cpp_option.deferred_opt[i];

      if (opt->code == OPT_D)
	cpp_define (cpp_in, opt->arg);
      else if (opt->code == OPT_U)
	cpp_undef (cpp_in, opt->arg);
      else if (opt->code == OPT_A)
	{
	  if (opt->arg[0] == '-')
	    cpp_unassert (cpp_in, opt->arg + 1);
	  else
	    cpp_assert (cpp_in, opt->arg);
	}
      else if (opt->code == OPT_MT || opt->code == OPT_MQ)
	if (mkdeps *deps = cpp_get_deps (cpp_in))
	  deps_add_target (deps, opt->arg, opt->code == OPT_MQ);
    }

  /* Pre-defined macros for non-required INTEGER kind types.  */
  for (gfc_integer_info *itype = gfc_integer_kinds; itype->kind != 0; itype++)
    {
      if (itype->kind == 1)
	cpp_define (cpp_in, "__GFC_INT_1__=1");
      if (itype->kind == 2)
	cpp_define (cpp_in, "__GFC_INT_2__=1");
      if (itype->kind == 8)
	cpp_define (cpp_in, "__GFC_INT_8__=1");
      if (itype->kind == 16)
	cpp_define (cpp_in, "__GFC_INT_16__=1");
    }

  /* Pre-defined macros for non-required REAL kind types.  */
  for (gfc_real_info *rtype = gfc_real_kinds; rtype->kind != 0; rtype++)
    {
      if (rtype->kind == 10)
	cpp_define (cpp_in, "__GFC_REAL_10__=1");
      if (rtype->kind == 16)
	cpp_define (cpp_in, "__GFC_REAL_16__=1");
    }

  if (gfc_cpp_option.working_directory
      && gfc_cpp_option.preprocess_only && !gfc_cpp_option.no_line_commands)
    pp_dir_change (cpp_in, get_src_pwd ());
}

bool
gfc_cpp_preprocess (const char *source_file)
{
  if (!gfc_cpp_enabled ())
    return false;

  cpp_change_file (cpp_in, LC_RENAME, source_file);

  if (cpp_option->traditional)
    scan_translation_unit_trad (cpp_in);
  else
    scan_translation_unit (cpp_in);

  /* -dM command line option.  */
  if (gfc_cpp_preprocess_only () &&
      gfc_cpp_option.dump_macros == 'M')
    {
      putc ('\n', print.outf);
      cpp_forall_identifiers (cpp_in, dump_macro, NULL);
    }

  putc ('\n', print.outf);

  if (!gfc_cpp_preprocess_only ()
      || (gfc_cpp_preprocess_only () && gfc_cpp_option.output_filename))
    fclose (print.outf);

  return true;
}

void
gfc_cpp_done (void)
{
  if (!gfc_cpp_enabled ())
    return;

  gcc_assert (cpp_in);

  if (gfc_cpp_makedep ())
    {
      if (gfc_cpp_option.deps_filename)
	{
	  FILE *f = fopen (gfc_cpp_option.deps_filename, "w");
	  if (f)
	    {
	      cpp_finish (cpp_in, f);
	      fclose (f);
	    }
	  else
	    gfc_fatal_error ("opening output file %qs: %s",
			     gfc_cpp_option.deps_filename,
			     xstrerror (errno));
	}
      else
	cpp_finish (cpp_in, stdout);
    }

  cpp_undef_all (cpp_in);
  cpp_clear_file_cache (cpp_in);
}

/* PATH must be malloc-ed and NULL-terminated.  */
void
gfc_cpp_add_include_path (char *path, bool user_supplied)
{
  /* CHAIN sets cpp_dir->sysp which differs from 0 if PATH is a system
     include path. Fortran does not define any system include paths.  */
  int cxx_aware = 0;

  add_path (path, INC_BRACKET, cxx_aware, user_supplied);
}

void
gfc_cpp_add_include_path_after (char *path, bool user_supplied)
{
  int cxx_aware = 0;
  add_path (path, INC_AFTER, cxx_aware, user_supplied);
}

void
gfc_cpp_register_include_paths (void)
{
  int cxx_stdinc = 0;
  register_include_chains (cpp_in, gfc_cpp_option.sysroot,
			   gfc_cpp_option.prefix, gfc_cpp_option.multilib,
			   gfc_cpp_option.standard_include_paths, cxx_stdinc,
			   gfc_cpp_option.verbose);
}



static void scan_translation_unit_trad (cpp_reader *);
static void account_for_newlines (const unsigned char *, size_t);
static int dump_macro (cpp_reader *, cpp_hashnode *, void *);

static void print_line (location_t, const char *);
static void maybe_print_line (location_t);


/* Writes out the preprocessed file, handling spacing and paste
   avoidance issues.  */
static void
scan_translation_unit (cpp_reader *pfile)
{
  bool avoid_paste = false;

  print.source = NULL;
  for (;;)
    {
      const cpp_token *token = cpp_get_token (pfile);

      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)
	{
	  if (print.source == NULL)
	    print.source = token;
	  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)
	putc (' ', print.outf);

      avoid_paste = false;
      print.source = NULL;
      print.prev = token;
      cpp_output_token (token, print.outf);

      if (token->type == CPP_COMMENT)
	account_for_newlines (token->val.str.text, token->val.str.len);
    }
}

/* Adjust print.src_line for newlines embedded in output.  */
static void
account_for_newlines (const unsigned char *str, size_t len)
{
  while (len--)
    if (*str++ == '\n')
      print.src_line++;
}

/* 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);
    }
}

/* If the token read on logical line LINE needs to be output on a
   different line to the current one, output the required newlines or
   a line marker.  */
static void
maybe_print_line (location_t src_loc)
{
  const line_map_ordinary *map
    = linemap_check_ordinary (linemap_lookup (line_table, src_loc));
  int src_line = SOURCE_LINE (map, src_loc);

  /* End the previous line of text.  */
  if (print.printed)
    {
      putc ('\n', print.outf);
      print.src_line++;
      print.printed = 0;
    }

  if (src_line >= print.src_line && src_line < print.src_line + 8)
    {
      while (src_line > print.src_line)
	{
	  putc ('\n', print.outf);
	  print.src_line++;
	}
    }
  else
    print_line (src_loc, "");
}

/* Output a line marker for logical line LINE.  Special flags are "1"
   or "2" indicating entering or leaving a file.  */
static void
print_line (location_t src_loc, const char *special_flags)
{
  /* End any previous line of text.  */
  if (print.printed)
    putc ('\n', print.outf);
  print.printed = 0;

  if (!gfc_cpp_option.no_line_commands)
    {
      expanded_location loc;
      size_t to_file_len;
      unsigned char *to_file_quoted;
      unsigned char *p;
      int sysp;

      loc = expand_location (src_loc);
      to_file_len = strlen (loc.file);
      to_file_quoted = (unsigned char *) alloca (to_file_len * 4 + 1);

      print.src_line = loc.line;

      /* cpp_quote_string does not nul-terminate, so we have to do it
	 ourselves.  */
      p = cpp_quote_string (to_file_quoted,
			    (const unsigned char *) loc.file, to_file_len);
      *p = '\0';
      fprintf (print.outf, "# %u \"%s\"%s",
	       print.src_line == 0 ? 1 : print.src_line,
	       to_file_quoted, special_flags);

      sysp = in_system_header_at (src_loc);
      if (sysp == 2)
	fputs (" 3 4", print.outf);
      else if (sysp == 1)
	fputs (" 3", print.outf);

      putc ('\n', print.outf);
    }
}

static void
cb_file_change (cpp_reader * ARG_UNUSED (pfile), const line_map_ordinary *map)
{
  const char *flags = "";

  if (gfc_cpp_option.no_line_commands)
    return;

  if (!map)
    return;

      if (print.first_time)
	{
	  /* Avoid printing foo.i when the main file is foo.c.  */
	  if (!cpp_get_options (cpp_in)->preprocessed)
	    print_line (map->start_location, flags);
	  print.first_time = 0;
	}
      else
	{
	  /* Bring current file to correct line when entering a new file.  */
	  if (map->reason == LC_ENTER)
	    maybe_print_line (linemap_included_from (map));
	  if (map->reason == LC_ENTER)
	    flags = " 1";
	  else if (map->reason == LC_LEAVE)
	    flags = " 2";
	  print_line (map->start_location, flags);
	}

}

/* 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)
{
  location_t src_loc = token->src_loc;

  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 line_map_ordinary *map
	= linemap_check_ordinary (linemap_lookup (line_table, src_loc));
      int spaces = SOURCE_COLUMN (map, src_loc) - 2;
      print.printed = 1;

      while (-- spaces >= 0)
	putc (' ', print.outf);
    }
}

static void
cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
	  const cpp_string *str)
{
  maybe_print_line (line);
  fprintf (print.outf, "#ident %s\n", str->text);
  print.src_line++;
}

static void
cb_define (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
           cpp_hashnode *node ATTRIBUTE_UNUSED)
{
  maybe_print_line (line);
  fputs ("#define ", print.outf);

  /* 'D' is whole definition; 'N' is name only.  */
  if (gfc_cpp_option.dump_macros == 'D')
    fputs ((const char *) cpp_macro_definition (pfile, node),
	   print.outf);
  else
    fputs ((const char *) NODE_NAME (node), print.outf);

  putc ('\n', print.outf);
  if (LOCATION_LINE (line) != 0)
    print.src_line++;
}

static void
cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
	  cpp_hashnode *node)
{
  maybe_print_line (line);
  fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
  print.src_line++;
}

static void
cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
	    const unsigned char *dir, const char *header, int angle_brackets,
	    const cpp_token **comments)
{
  maybe_print_line (line);
  if (angle_brackets)
    fprintf (print.outf, "#%s <%s>", dir, header);
  else
    fprintf (print.outf, "#%s \"%s\"", dir, header);

  if (comments != NULL)
    {
      while (*comments != NULL)
	{
	  if ((*comments)->flags & PREV_WHITE)
	    putc (' ', print.outf);
	  cpp_output_token (*comments, print.outf);
	  ++comments;
	}
    }

  putc ('\n', print.outf);
  print.src_line++;
}

/* Dump out the hash table.  */
static int
dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
{
  if (cpp_user_macro_p (node))
    {
      fputs ("#define ", print.outf);
      fputs ((const char *) cpp_macro_definition (pfile, node),
	     print.outf);
      putc ('\n', print.outf);
      print.src_line++;
    }

  return 1;
}

static void
cb_used_define (cpp_reader *pfile, location_t line ATTRIBUTE_UNUSED,
		cpp_hashnode *node)
{
  gfc_cpp_macro_queue *q;
  q = XNEW (gfc_cpp_macro_queue);
  q->macro = xstrdup ((const char *) cpp_macro_definition (pfile, node));
  q->next = cpp_define_queue;
  cpp_define_queue = q;
}

/* Callback from cpp_error for PFILE to print diagnostics from the
   preprocessor.  The diagnostic is of type LEVEL, with REASON set
   to the reason code if LEVEL is represents a warning, at location
   RICHLOC; MSG is the translated message and AP the arguments.
   Returns true if a diagnostic was emitted, false otherwise.  */

static bool
cb_cpp_diagnostic (cpp_reader *pfile ATTRIBUTE_UNUSED,
		   enum cpp_diagnostic_level level,
		   enum cpp_warning_reason reason,
		   rich_location *richloc,
		   const char *msg, va_list *ap)
{
  diagnostic_info diagnostic;
  diagnostic_t dlevel;
  bool save_warn_system_headers = global_dc->dc_warn_system_headers;
  bool ret;

  switch (level)
    {
    case CPP_DL_WARNING_SYSHDR:
      global_dc->dc_warn_system_headers = 1;
      /* Fall through.  */
    case CPP_DL_WARNING:
      dlevel = DK_WARNING;
      break;
    case CPP_DL_PEDWARN:
      dlevel = DK_PEDWARN;
      break;
    case CPP_DL_ERROR:
      dlevel = DK_ERROR;
      break;
    case CPP_DL_ICE:
      dlevel = DK_ICE;
      break;
    case CPP_DL_NOTE:
      dlevel = DK_NOTE;
      break;
    case CPP_DL_FATAL:
      dlevel = DK_FATAL;
      break;
    default:
      gcc_unreachable ();
    }
  diagnostic_set_info_translated (&diagnostic, msg, ap,
				  richloc, dlevel);
  if (reason == CPP_W_WARNING_DIRECTIVE)
    diagnostic_override_option_index (&diagnostic, OPT_Wcpp);
  ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
  if (level == CPP_DL_WARNING_SYSHDR)
    global_dc->dc_warn_system_headers = save_warn_system_headers;
  return ret;
}

/* Callback called when -fworking-director and -E to emit working
   directory in cpp output file.  */

void
pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
{
  size_t to_file_len = strlen (dir);
  unsigned char *to_file_quoted =
     (unsigned char *) alloca (to_file_len * 4 + 1);
  unsigned char *p;

  /* cpp_quote_string does not nul-terminate, so we have to do it ourselves.  */
  p = cpp_quote_string (to_file_quoted, (const unsigned char *) dir, to_file_len);
  *p = '\0';
  fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted);
}

/* Copy a #pragma directive to the preprocessed output.  */
static void
cb_def_pragma (cpp_reader *pfile, location_t line)
{
  maybe_print_line (line);
  fputs ("#pragma ", print.outf);
  cpp_output_line (pfile, print.outf);
  print.src_line++;
}

static void
cb_used_undef (cpp_reader *pfile ATTRIBUTE_UNUSED,
	       location_t line ATTRIBUTE_UNUSED,
	       cpp_hashnode *node)
{
  gfc_cpp_macro_queue *q;
  q = XNEW (gfc_cpp_macro_queue);
  q->macro = xstrdup ((const char *) NODE_NAME (node));
  q->next = cpp_undefine_queue;
  cpp_undefine_queue = q;
}

static void
dump_queued_macros (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
  gfc_cpp_macro_queue *q;

  /* End the previous line of text.  */
  if (print.printed)
    {
      putc ('\n', print.outf);
      print.src_line++;
      print.printed = 0;
    }

  for (q = cpp_define_queue; q;)
    {
      gfc_cpp_macro_queue *oq;
      fputs ("#define ", print.outf);
      fputs (q->macro, print.outf);
      putc ('\n', print.outf);
      print.src_line++;
      oq = q;
      q = q->next;
      free (oq->macro);
      free (oq);
    }
  cpp_define_queue = NULL;
  for (q = cpp_undefine_queue; q;)
    {
      gfc_cpp_macro_queue *oq;
      fprintf (print.outf, "#undef %s\n", q->macro);
      print.src_line++;
      oq = q;
      q = q->next;
      free (oq->macro);
      free (oq);
    }
  cpp_undefine_queue = NULL;
}
