/* Part of CPP library.  File handling.
   Copyright (C) 1986-2021 Free Software Foundation, Inc.
   Written by Per Bothner, 1994.
   Based on CCCP program by Paul Rubin, June 1986
   Adapted to ANSI C, Richard Stallman, Jan 1987
   Split out of cpplib.c, Zack Weinberg, Oct 1998
   Reimplemented, Neil Booth, Jul 2003

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"
#include "mkdeps.h"
#include "obstack.h"
#include "hashtab.h"
#include "md5.h"
#include <dirent.h>

/* Variable length record files on VMS will have a stat size that includes
   record control characters that won't be included in the read size.  */
#ifdef VMS
# define FAB_C_VAR 2 /* variable length records (see Starlet fabdef.h) */
# define STAT_SIZE_RELIABLE(ST) ((ST).st_fab_rfm != FAB_C_VAR)
#else
# define STAT_SIZE_RELIABLE(ST) true
#endif

#ifdef __DJGPP__
#include <io.h>
  /* For DJGPP redirected input is opened in text mode.  */
#  define set_stdin_to_binary_mode() \
     if (! isatty (0)) setmode (0, O_BINARY)
#else
#  define set_stdin_to_binary_mode() /* Nothing */
#endif

/* This structure represents a file searched for by CPP, whether it
   exists or not.  An instance may be pointed to by more than one
   cpp_file_hash_entry; at present no reference count is kept.  */
struct _cpp_file
{
  /* Filename as given to #include or command line switch.  */
  const char *name;

  /* The full path used to find the file.  */
  const char *path;

  /* The full path of the pch file.  */
  const char *pchname;

  /* The file's path with the basename stripped.  NULL if it hasn't
     been calculated yet.  */
  const char *dir_name;

  /* Chain through all files.  */
  struct _cpp_file *next_file;

  /* The contents of NAME after calling read_file().  */
  const uchar *buffer;

  /* Pointer to the real start of BUFFER.  read_file() might increment
     BUFFER; when freeing, this this pointer must be used instead.  */
  const uchar *buffer_start;

  /* The macro, if any, preventing re-inclusion.  */
  const cpp_hashnode *cmacro;

  /* The directory in the search path where FILE was found.  Used for
     #include_next and determining whether a header is a system
     header.  */
  cpp_dir *dir;

  /* As filled in by stat(2) for the file.  */
  struct stat st;

  /* File descriptor.  Invalid if -1, otherwise open.  */
  int fd;

  /* Zero if this file was successfully opened and stat()-ed,
     otherwise errno obtained from failure.  */
  int err_no;

  /* Number of times the file has been stacked for preprocessing.  */
  unsigned short stack_count;

  /* If opened with #import or contains #pragma once.  */
  bool once_only : 1;

  /* If read() failed before.  */
  bool dont_read : 1;

  /* If BUFFER above contains the true contents of the file.  */
  bool buffer_valid : 1;

  /* If this file is implicitly preincluded.  */
  bool implicit_preinclude : 1;

  /* > 0: Known C++ Module header unit, <0: known not.  ==0, unknown  */
  int header_unit : 2;
};

/* A singly-linked list for all searches for a given file name, with
   its head pointed to by a slot in FILE_HASH.  The file name is what
   appeared between the quotes in a #include directive; it can be
   determined implicitly from the hash table location or explicitly
   from FILE->name.

   FILE is a structure containing details about the file that was
   found with that search, or details of how the search failed.

   START_DIR is the starting location of the search in the include
   chain.  The current directories for "" includes are also hashed in
   the hash table and therefore unique.  Files that are looked up
   without using a search path, such as absolute filenames and file
   names from the command line share a special starting directory so
   they don't cause cache hits with normal include-chain lookups.

   If START_DIR is NULL then the entry is for a directory, not a file,
   and the directory is in DIR.  Since the starting point in a file
   lookup chain is never NULL, this means that simple pointer
   comparisons against START_DIR can be made to determine cache hits
   in file lookups.

   If a cache lookup fails because of e.g. an extra "./" in the path,
   then nothing will break.  It is just less efficient as CPP will
   have to do more work re-preprocessing the file, and/or comparing
   its contents against earlier once-only files.
*/
struct cpp_file_hash_entry
{
  struct cpp_file_hash_entry *next;
  cpp_dir *start_dir;
  location_t location;
  union
  {
    _cpp_file *file;
    cpp_dir *dir;
  } u;
};

/* Number of entries to put in a cpp_file_hash_entry pool.  */
#define FILE_HASH_POOL_SIZE 127

/* A file hash entry pool.  We allocate cpp_file_hash_entry object from
   one of these.  */
struct file_hash_entry_pool
{
  /* Number of entries used from this pool.  */
  unsigned int file_hash_entries_used;
  /* Next pool in the chain; used when freeing.  */
  struct file_hash_entry_pool *next;
  /* The memory pool.  */
  struct cpp_file_hash_entry pool[FILE_HASH_POOL_SIZE];
};

static bool open_file (_cpp_file *file);
static bool pch_open_file (cpp_reader *pfile, _cpp_file *file,
			   bool *invalid_pch);
static bool find_file_in_dir (cpp_reader *pfile, _cpp_file *file,
			      bool *invalid_pch, location_t loc);
static bool read_file_guts (cpp_reader *pfile, _cpp_file *file,
			    location_t loc, const char *input_charset);
static bool read_file (cpp_reader *pfile, _cpp_file *file,
		       location_t loc);
static struct cpp_dir *search_path_head (cpp_reader *, const char *fname,
				 int angle_brackets, enum include_type);
static const char *dir_name_of_file (_cpp_file *file);
static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int,
			      location_t);
static struct cpp_file_hash_entry *search_cache (struct cpp_file_hash_entry *head,
					     const cpp_dir *start_dir);
static _cpp_file *make_cpp_file (cpp_dir *, const char *fname);
static void destroy_cpp_file (_cpp_file *);
static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp);
static void allocate_file_hash_entries (cpp_reader *pfile);
static struct cpp_file_hash_entry *new_file_hash_entry (cpp_reader *pfile);
static int report_missing_guard (void **slot, void *b);
static hashval_t file_hash_hash (const void *p);
static int file_hash_eq (const void *p, const void *q);
static char *read_filename_string (int ch, FILE *f);
static void read_name_map (cpp_dir *dir);
static char *remap_filename (cpp_reader *pfile, _cpp_file *file);
static char *append_file_to_dir (const char *fname, cpp_dir *dir);
static bool validate_pch (cpp_reader *, _cpp_file *file, const char *pchname);
static int pchf_save_compare (const void *e1, const void *e2);
static int pchf_compare (const void *d_p, const void *e_p);
static bool check_file_against_entries (cpp_reader *, _cpp_file *, bool);

/* Given a filename in FILE->PATH, with the empty string interpreted
   as <stdin>, open it.

   On success FILE contains an open file descriptor and stat
   information for the file.  On failure the file descriptor is -1 and
   the appropriate errno is also stored in FILE.  Returns TRUE iff
   successful.

   We used to open files in nonblocking mode, but that caused more
   problems than it solved.  Do take care not to acquire a controlling
   terminal by mistake (this can't happen on sane systems, but
   paranoia is a virtue).

   Use the three-argument form of open even though we aren't
   specifying O_CREAT, to defend against broken system headers.

   O_BINARY tells some runtime libraries (notably DJGPP) not to do
   newline translation; we can handle DOS line breaks just fine
   ourselves.  */
static bool
open_file (_cpp_file *file)
{
  if (file->path[0] == '\0')
    {
      file->fd = 0;
      set_stdin_to_binary_mode ();
    }
  else
    file->fd = open (file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666);

  if (file->fd != -1)
    {
      if (fstat (file->fd, &file->st) == 0)
	{
	  if (!S_ISDIR (file->st.st_mode))
	    {
	      file->err_no = 0;
	      return true;
	    }

	  /* Ignore a directory and continue the search.  The file we're
	     looking for may be elsewhere in the search path.  */
	  errno = ENOENT;
	}

      close (file->fd);
      file->fd = -1;
    }
#if defined(_WIN32) && !defined(__CYGWIN__)
  else if (errno == EACCES)
    {
      /* On most UNIX systems, open succeeds on a directory.  Above,
         we check if we have opened a directory and if so, set errno
         to ENOENT.  However, on Windows, opening a directory
         fails with EACCES.  We want to return ENOENT in that
         case too.  */
      if (stat (file->path, &file->st) == 0
          && S_ISDIR (file->st.st_mode))
        errno = ENOENT;
      else
	/* The call to stat may have reset errno.  */
	errno = EACCES;
    }
#endif    
  else if (errno == ENOTDIR)
    errno = ENOENT;

  file->err_no = errno;

  return false;
}

/* Temporary PCH intercept of opening a file.  Try to find a PCH file
   based on FILE->name and FILE->dir, and test those found for
   validity using PFILE->cb.valid_pch.  Return true iff a valid file is
   found.  Set *INVALID_PCH if a PCH file is found but wasn't valid.  */

static bool
pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
{
  static const char extension[] = ".gch";
  const char *path = file->path;
  size_t len, flen;
  char *pchname;
  struct stat st;
  bool valid = false;

  /* No PCH on <stdin> or if not requested.  */
  if (file->name[0] == '\0' || !pfile->cb.valid_pch)
    return false;

  /* If the file is not included as first include from either the toplevel
     file or the command-line it is not a valid use of PCH.  */
  for (_cpp_file *f = pfile->all_files; f; f = f->next_file)
    if (f->implicit_preinclude)
      continue;
    else if (pfile->main_file == f)
      break;
    else
      return false;

  flen = strlen (path);
  len = flen + sizeof (extension);
  pchname = XNEWVEC (char, len);
  memcpy (pchname, path, flen);
  memcpy (pchname + flen, extension, sizeof (extension));

  if (stat (pchname, &st) == 0)
    {
      DIR *pchdir;
      struct dirent *d;
      size_t dlen, plen = len;

      if (!S_ISDIR (st.st_mode))
	valid = validate_pch (pfile, file, pchname);
      else if ((pchdir = opendir (pchname)) != NULL)
	{
	  pchname[plen - 1] = '/';
	  while ((d = readdir (pchdir)) != NULL)
	    {
	      dlen = strlen (d->d_name) + 1;
	      if ((strcmp (d->d_name, ".") == 0)
		  || (strcmp (d->d_name, "..") == 0))
		continue;
	      if (dlen + plen > len)
		{
		  len += dlen + 64;
		  pchname = XRESIZEVEC (char, pchname, len);
		}
	      memcpy (pchname + plen, d->d_name, dlen);
	      valid = validate_pch (pfile, file, pchname);
	      if (valid)
		break;
	    }
	  closedir (pchdir);
	}
      if (!valid)
	*invalid_pch = true;
    }

  if (valid)
    file->pchname = pchname;
  else
    free (pchname);

  return valid;
}

/* Canonicalize the path to FILE.  Return the canonical form if it is
   shorter, otherwise return NULL.  This function does NOT free the
   memory pointed by FILE.  */

static char *
maybe_shorter_path (const char * file)
{
  char * file2 = lrealpath (file);
  if (file2 && strlen (file2) < strlen (file))
    {
      return file2;
    }
  else 
    {
      free (file2);
      return NULL;
    }
}

/* Try to open the path FILE->name appended to FILE->dir.  This is
   where remap and PCH intercept the file lookup process.  Return true
   if the file was found, whether or not the open was successful.
   Set *INVALID_PCH to true if a PCH file is found but wasn't valid.
   Use LOC when emitting any diagnostics.  */

static bool
find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch,
		  location_t loc)
{
  char *path;

  if (CPP_OPTION (pfile, remap) && (path = remap_filename (pfile, file)))
    ;
  else
    if (file->dir->construct)
      path = file->dir->construct (file->name, file->dir);
    else
      path = append_file_to_dir (file->name, file->dir);

  if (path)
    {
      hashval_t hv;
      char *copy;
      void **pp;

      /* We try to canonicalize system headers.  For DOS based file
       * system, we always try to shorten non-system headers, as DOS
       * has a tighter constraint on max path length.  */
      if ((CPP_OPTION (pfile, canonical_system_headers) && file->dir->sysp)
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
	  || !file->dir->sysp
#endif
	 )
	{
	  char * canonical_path = maybe_shorter_path (path);
	  if (canonical_path)
	    {
	      /* The canonical path was newly allocated.  Let's free the
		 non-canonical one.  */
	      free (path);
	      path = canonical_path;
	    }
	}

      hv = htab_hash_string (path);
      if (htab_find_with_hash (pfile->nonexistent_file_hash, path, hv) != NULL)
	{
	  file->err_no = ENOENT;
	  return false;
	}

      file->path = path;
      if (pch_open_file (pfile, file, invalid_pch))
	return true;

      if (open_file (file))
	return true;

      if (file->err_no != ENOENT)
	{
	  open_file_failed (pfile, file, 0, loc);
	  return true;
	}

      /* We copy the path name onto an obstack partly so that we don't
	 leak the memory, but mostly so that we don't fragment the
	 heap.  */
      copy = (char *) obstack_copy0 (&pfile->nonexistent_file_ob, path,
				     strlen (path));
      free (path);
      pp = htab_find_slot_with_hash (pfile->nonexistent_file_hash,
				     copy, hv, INSERT);
      *pp = copy;

      file->path = file->name;
    }
  else
    {
      file->err_no = ENOENT; 
      file->path = NULL;
    }

  return false;
}

/* Return true iff the missing_header callback found the given HEADER.  */
static bool
search_path_exhausted (cpp_reader *pfile, const char *header, _cpp_file *file)
{
  missing_header_cb func = pfile->cb.missing_header;

  /* When the regular search path doesn't work, try context dependent
     headers search paths.  */
  if (func
      && file->dir == NULL)
    {
      if ((file->path = func (pfile, header, &file->dir)) != NULL)
	{
	  if (open_file (file))
	    return true;
	  free ((void *)file->path);
	}
      file->path = file->name;
    }

  return false;
}

bool
_cpp_find_failed (_cpp_file *file)
{
  return file->err_no != 0;
}

/* Given a filename FNAME search for such a file in the include path
   starting from START_DIR.  If FNAME is the empty string it is
   interpreted as STDIN if START_DIR is PFILE->no_search_path.

   If the file is not found in the file cache fall back to the O/S and
   add the result to our cache.

   If the file was not found in the filesystem, or there was an error
   opening it, then ERR_NO is nonzero and FD is -1.  If the file was
   found, then ERR_NO is zero and FD could be -1 or an open file
   descriptor.  FD can be -1 if the file was found in the cache and
   had previously been closed.  To open it again pass the return value
   to open_file().

   If KIND is _cpp_FFK_PRE_INCLUDE then it is OK for the file to be
   missing.  If present, it is OK for a precompiled header to be
   included after it.

   Use LOC as the location for any errors.  */

_cpp_file *
_cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir,
		int angle_brackets, _cpp_find_file_kind kind, location_t loc)
{
  bool invalid_pch = false;
  bool saw_bracket_include = false;
  bool saw_quote_include = false;
  struct cpp_dir *found_in_cache = NULL;

  /* Ensure we get no confusion between cached files and directories.  */
  if (start_dir == NULL)
    cpp_error_at (pfile, CPP_DL_ICE, loc, "NULL directory in find_file");

  void **hash_slot
    = htab_find_slot_with_hash (pfile->file_hash, fname,
				htab_hash_string (fname), INSERT);

  /* First check the cache before we resort to memory allocation.  */
  cpp_file_hash_entry *entry
    = search_cache ((struct cpp_file_hash_entry *) *hash_slot, start_dir);
  if (entry)
    return entry->u.file;

  _cpp_file *file = make_cpp_file (start_dir, fname);
  file->implicit_preinclude
    = (kind == _cpp_FFK_PRE_INCLUDE
       || (pfile->buffer && pfile->buffer->file->implicit_preinclude));

  if (kind != _cpp_FFK_FAKE)
    /* Try each path in the include chain.  */
    for (;;)
      {
	if (find_file_in_dir (pfile, file, &invalid_pch, loc))
	  break;

	file->dir = file->dir->next;
	if (file->dir == NULL)
	  {
	    if (search_path_exhausted (pfile, fname, file))
	      {
		/* Although this file must not go in the cache,
		   because the file found might depend on things (like
		   the current file) that aren't represented in the
		   cache, it still has to go in the list of all files
		   so that #import works.  */
		file->next_file = pfile->all_files;
		pfile->all_files = file;
		if (*hash_slot == NULL)
		  {
		    /* If *hash_slot is NULL, the above
		       htab_find_slot_with_hash call just created the
		       slot, but we aren't going to store there
		       anything, so need to remove the newly created
		       entry.  htab_clear_slot requires that it is
		       non-NULL, so store there some non-NULL pointer,
		       htab_clear_slot will overwrite it
		       immediately.  */
		    *hash_slot = file;
		    htab_clear_slot (pfile->file_hash, hash_slot);
		  }
		return file;
	      }

	    if (invalid_pch)
	      {
		cpp_error (pfile, CPP_DL_ERROR,
			   "one or more PCH files were found,"
			   " but they were invalid");
		if (!cpp_get_options (pfile)->warn_invalid_pch)
		  cpp_error (pfile, CPP_DL_NOTE,
			     "use -Winvalid-pch for more information");
	      }

	    if (kind == _cpp_FFK_PRE_INCLUDE)
	      {
		free ((char *) file->name);
		free (file);
		if (*hash_slot == NULL)
		  {
		    /* See comment on the above htab_clear_slot call.  */
		    *hash_slot = file;
		    htab_clear_slot (pfile->file_hash, hash_slot);
		  }
		return NULL;
	      }

	    if (kind != _cpp_FFK_HAS_INCLUDE)
	      open_file_failed (pfile, file, angle_brackets, loc);
	    break;
	  }

	/* Only check the cache for the starting location (done above)
	   and the quote and bracket chain heads because there are no
	   other possible starting points for searches.  */
	if (file->dir == pfile->bracket_include)
	  saw_bracket_include = true;
	else if (file->dir == pfile->quote_include)
	  saw_quote_include = true;
	else
	  continue;

	entry
	  = search_cache ((struct cpp_file_hash_entry *) *hash_slot, file->dir);
	if (entry)
	  {
	    found_in_cache = file->dir;
	    break;
	  }
      }

  if (entry)
    {
      /* Cache for START_DIR too, sharing the _cpp_file structure.  */
      free ((char *) file->name);
      free (file);
      file = entry->u.file;
    }
  else
    {
      /* This is a new file; put it in the list.  */
      file->next_file = pfile->all_files;
      pfile->all_files = file;
    }

  /* Store this new result in the hash table.  */
  entry = new_file_hash_entry (pfile);
  entry->next = (struct cpp_file_hash_entry *) *hash_slot;
  entry->start_dir = start_dir;
  entry->location = loc;
  entry->u.file = file;
  *hash_slot = (void *) entry;

  /* If we passed the quote or bracket chain heads, cache them also.
     This speeds up processing if there are lots of -I options.  */
  if (saw_bracket_include
      && pfile->bracket_include != start_dir
      && found_in_cache != pfile->bracket_include)
    {
      entry = new_file_hash_entry (pfile);
      entry->next = (struct cpp_file_hash_entry *) *hash_slot;
      entry->start_dir = pfile->bracket_include;
      entry->location = loc;
      entry->u.file = file;
      *hash_slot = (void *) entry;
    }
  if (saw_quote_include
      && pfile->quote_include != start_dir
      && found_in_cache != pfile->quote_include)
    {
      entry = new_file_hash_entry (pfile);
      entry->next = (struct cpp_file_hash_entry *) *hash_slot;
      entry->start_dir = pfile->quote_include;
      entry->location = loc;
      entry->u.file = file;
      *hash_slot = (void *) entry;
    }

  return file;
}

/* Read a file into FILE->buffer, returning true on success.

   If FILE->fd is something weird, like a block device, we don't want
   to read it at all.  Don't even try to figure out what something is,
   except for plain files and block devices, since there is no
   reliable portable way of doing this.

   Use LOC for any diagnostics.

   PFILE may be NULL.  In this case, no diagnostics are issued.

   FIXME: Flush file cache and try again if we run out of memory.  */
static bool
read_file_guts (cpp_reader *pfile, _cpp_file *file, location_t loc,
		const char *input_charset)
{
  ssize_t size, total, count;
  uchar *buf;
  bool regular;

  if (S_ISBLK (file->st.st_mode))
    {
      if (pfile)
	cpp_error_at (pfile, CPP_DL_ERROR, loc,
		      "%s is a block device", file->path);
      return false;
    }

  regular = S_ISREG (file->st.st_mode) != 0;
  if (regular)
    {
      /* off_t might have a wider range than ssize_t - in other words,
	 the max size of a file might be bigger than the address
	 space.  We can't handle a file that large.  (Anyone with
	 a single source file bigger than 2GB needs to rethink
	 their coding style.)  Some systems (e.g. AIX 4.1) define
	 SSIZE_MAX to be much smaller than the actual range of the
	 type.  Use INTTYPE_MAXIMUM unconditionally to ensure this
	 does not bite us.  */
      if (file->st.st_size > INTTYPE_MAXIMUM (ssize_t))
	{
	  if (pfile)
	    cpp_error_at (pfile, CPP_DL_ERROR, loc,
			  "%s is too large", file->path);
	  return false;
	}

      size = file->st.st_size;
    }
  else
    /* 8 kilobytes is a sensible starting size.  It ought to be bigger
       than the kernel pipe buffer, and it's definitely bigger than
       the majority of C source files.  */
    size = 8 * 1024;

  /* The + 16 here is space for the final '\n' and 15 bytes of padding,
     used to quiet warnings from valgrind or Address Sanitizer, when the
     optimized lexer accesses aligned 16-byte memory chunks, including
     the bytes after the malloced, area, and stops lexing on '\n'.  */
  buf = XNEWVEC (uchar, size + 16);
  total = 0;
  while ((count = read (file->fd, buf + total, size - total)) > 0)
    {
      total += count;

      if (total == size)
	{
	  if (regular)
	    break;
	  size *= 2;
	  buf = XRESIZEVEC (uchar, buf, size + 16);
	}
    }

  if (count < 0)
    {
      if (pfile)
	cpp_errno_filename (pfile, CPP_DL_ERROR, file->path, loc);
      free (buf);
      return false;
    }

  if (pfile && regular && total != size && STAT_SIZE_RELIABLE (file->st))
    cpp_error_at (pfile, CPP_DL_WARNING, loc,
	       "%s is shorter than expected", file->path);

  file->buffer = _cpp_convert_input (pfile,
				     input_charset,
				     buf, size + 16, total,
				     &file->buffer_start,
				     &file->st.st_size);
  file->buffer_valid = file->buffer;
  return file->buffer_valid;
}

/* Convenience wrapper around read_file_guts that opens the file if
   necessary and closes the file descriptor after reading.  FILE must
   have been passed through find_file() at some stage.  Use LOC for
   any diagnostics.  Unlike read_file_guts(), PFILE may not be NULL.  */
static bool
read_file (cpp_reader *pfile, _cpp_file *file, location_t loc)
{
  /* If we already have its contents in memory, succeed immediately.  */
  if (file->buffer_valid)
    return true;

  /* If an earlier read failed for some reason don't try again.  */
  if (file->dont_read || file->err_no)
    return false;

  if (file->fd == -1 && !open_file (file))
    {
      open_file_failed (pfile, file, 0, loc);
      return false;
    }

  file->dont_read = !read_file_guts (pfile, file, loc,
				     CPP_OPTION (pfile, input_charset));
  close (file->fd);
  file->fd = -1;

  return !file->dont_read;
}

/* Returns TRUE if FILE is already known to be idempotent, and should
   therefore not be read again.  */
static bool
is_known_idempotent_file (cpp_reader *pfile, _cpp_file *file, bool import)
{
  /* Skip once-only files.  */
  if (file->once_only)
    return true;

  /* We must mark the file once-only if #import now, before header
     guard checks.  Otherwise, undefining the header guard might
     cause the file to be re-stacked.  */
  if (import)
    {
      _cpp_mark_file_once_only (pfile, file);

      /* Don't stack files that have been stacked before.  */
      if (file->stack_count)
	return true;
    }

  /* Skip if the file had a header guard and the macro is defined.
     PCH relies on this appearing before the PCH handler below.  */
  if (file->cmacro && cpp_macro_p (file->cmacro))
    return true;

  /* Handle PCH files immediately; don't stack them.  */
  if (file->pchname)
    {
      pfile->cb.read_pch (pfile, file->pchname, file->fd, file->path);
      file->fd = -1;
      free ((void *) file->pchname);
      file->pchname = NULL;
      return true;
    }

  return false;
}

/* Return TRUE if file has unique contents, so we should read process
   it.  The file's contents must already have been read.  */

static bool
has_unique_contents (cpp_reader *pfile, _cpp_file *file, bool import,
		     location_t loc)
{
  /* Check the file against the PCH file.  This is done before
     checking against files we've already seen, since it may save on
     I/O.  */
  if (check_file_against_entries (pfile, file, import))
    {
      /* If this isn't a #import, but yet we can't include the file,
	 that means that it was #import-ed in the PCH file,
	 so we can never include it again.  */
      if (! import)
	_cpp_mark_file_once_only (pfile, file);
      return false;
    }

  /* Now we've read the file's contents, we can stack it if there
     are no once-only files.  */
  if (!pfile->seen_once_only)
    return true;

  /* We may have read the file under a different name.  Look
     for likely candidates and compare file contents to be sure.  */
  for (_cpp_file *f = pfile->all_files; f; f = f->next_file)
    {
      if (f == file)
	continue; /* It'sa me!  */

      if ((import || f->once_only)
	  && f->err_no == 0
	  && f->st.st_mtime == file->st.st_mtime
	  && f->st.st_size == file->st.st_size)
	{
	  _cpp_file *ref_file;

	  if (f->buffer && !f->buffer_valid)
	    {
	      /* We already have a buffer but it is not valid, because
		 the file is still stacked.  Make a new one.  */
	      ref_file = make_cpp_file (f->dir, f->name);
	      ref_file->path = f->path;
	    }
	  else
	    /* The file is not stacked anymore.  We can reuse it.  */
	    ref_file = f;

	  bool same_file_p = (read_file (pfile, ref_file, loc)
			      /* Size might have changed in read_file().  */
			      && ref_file->st.st_size == file->st.st_size
			      && !memcmp (ref_file->buffer, file->buffer,
					  file->st.st_size));

	  if (f->buffer && !f->buffer_valid)
	    {
	      ref_file->path = 0;
	      destroy_cpp_file (ref_file);
	    }

	  if (same_file_p)
	    /* Already seen under a different name.  */
	    return false;
	}
    }

  return true;
}

/* Place the file referenced by FILE into a new buffer on the buffer
   stack if possible.  Returns true if a buffer is stacked.  Use LOC
   for any diagnostics.  */

bool
_cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
		 location_t loc)
{
  if (is_known_idempotent_file (pfile, file, type == IT_IMPORT))
    return false;

  int sysp = 0;
  char *buf = nullptr;

  /* Check C++ module include translation.  */
  if (!file->header_unit && type < IT_HEADER_HWM
      /* Do not include translate include-next.  */
      && type != IT_INCLUDE_NEXT
      && pfile->cb.translate_include)
    buf = (pfile->cb.translate_include
	   (pfile, pfile->line_table, loc, file->path));

  if (buf)
    {
      /* We don't increment the line number at the end of a buffer,
	 because we don't usually need that location (we're popping an
	 include file).  However in this case we do want to do the
	 increment.  So push a writable buffer of two newlines to acheive
	 that.  (We also need an extra newline, so this looks like a regular
	 file, which we do that to to make sure we don't fall off the end in the
	 middle of a line.  */
      static uchar newlines[] = "\n\n\n";
      cpp_push_buffer (pfile, newlines, 2, true);

      size_t len = strlen (buf);
      buf[len] = '\n'; /* See above  */
      cpp_buffer *buffer
	= cpp_push_buffer (pfile, reinterpret_cast<unsigned char *> (buf),
			   len, true);
      buffer->to_free = buffer->buf;

      file->header_unit = +1;
      _cpp_mark_file_once_only (pfile, file);
    }
  else
    {
      /* Not a header unit, and we know it.  */
      file->header_unit = -1;

      if (!read_file (pfile, file, loc))
	return false;

      if (!has_unique_contents (pfile, file, type == IT_IMPORT, loc))
	return false;

      if (pfile->buffer && file->dir)
	sysp = MAX (pfile->buffer->sysp, file->dir->sysp);

      /* Add the file to the dependencies on its first inclusion.  */
      if (CPP_OPTION (pfile, deps.style) > (sysp != 0)
	  && !file->stack_count
	  && file->path[0]
	  && !(pfile->main_file == file
	       && CPP_OPTION (pfile, deps.ignore_main_file)))
	deps_add_dep (pfile->deps, file->path);

      /* Clear buffer_valid since _cpp_clean_line messes it up.  */
      file->buffer_valid = false;
      file->stack_count++;

      /* Stack the buffer.  */
      cpp_buffer *buffer
	= cpp_push_buffer (pfile, file->buffer, file->st.st_size,
			   CPP_OPTION (pfile, preprocessed)
			   && !CPP_OPTION (pfile, directives_only));
      buffer->file = file;
      buffer->sysp = sysp;
      buffer->to_free = file->buffer_start;

      /* Initialize controlling macro state.  */
      pfile->mi_valid = true;
      pfile->mi_cmacro = 0;
    }

  /* In the case of a normal #include, we're now at the start of the
     line *following* the #include.  A separate location_t for this
     location makes no sense, until we do the LC_LEAVE.

     This does not apply if we found a PCH file, we're not a regular
     include, or we ran out of locations.  */
  bool decrement = (file->pchname == NULL
		    && type < IT_DIRECTIVE_HWM
		    && (pfile->line_table->highest_location
			!= LINE_MAP_MAX_LOCATION - 1));
  if (decrement)
    pfile->line_table->highest_location--;

  if (file->header_unit <= 0)
    /* Add line map and do callbacks.  */
    _cpp_do_file_change (pfile, LC_ENTER, file->path,
		       /* With preamble injection, start on line zero,
			  so the preamble doesn't appear to have been
			  included from line 1.  Likewise when
			  starting preprocessed, we expect an initial
			  locating line.  */
			 type == IT_PRE_MAIN ? 0 : 1, sysp);
  else if (decrement)
    {
      /* Adjust the line back one so we appear on the #include line itself.  */
      const line_map_ordinary *map
	= LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table);
      linenum_type line = SOURCE_LINE (map, pfile->line_table->highest_line);
      linemap_line_start (pfile->line_table, line - 1, 0);
    }

  return true;
}

/* Mark FILE to be included once only.  */
void
_cpp_mark_file_once_only (cpp_reader *pfile, _cpp_file *file)
{
  pfile->seen_once_only = true;
  file->once_only = true;
}

/* Return the directory from which searching for FNAME should start,
   considering the directive TYPE and ANGLE_BRACKETS.  If there is
   nothing left in the path, returns NULL.  */
static struct cpp_dir *
search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets,
		  enum include_type type)
{
  cpp_dir *dir;
  _cpp_file *file;

  if (IS_ABSOLUTE_PATH (fname))
    return &pfile->no_search_path;

  /* pfile->buffer is NULL when processing an -include command-line flag.  */
  file = pfile->buffer == NULL ? pfile->main_file : pfile->buffer->file;

  /* For #include_next, skip in the search path past the dir in which
     the current file was found, but if it was found via an absolute
     path use the normal search logic.  */
  if (type == IT_INCLUDE_NEXT && file->dir
      && file->dir != &pfile->no_search_path)
    dir = file->dir->next;
  else if (angle_brackets)
    dir = pfile->bracket_include;
  else if (type == IT_CMDLINE)
    /* -include and -imacros use the #include "" chain with the
       preprocessor's cwd prepended.  */
    return make_cpp_dir (pfile, "./", false);
  else if (pfile->quote_ignores_source_dir)
    dir = pfile->quote_include;
  else
    return make_cpp_dir (pfile, dir_name_of_file (file),
			 pfile->buffer ? pfile->buffer->sysp : 0);

  if (dir == NULL)
    cpp_error (pfile, CPP_DL_ERROR,
	       "no include path in which to search for %s", fname);

  return dir;
}

/* Strip the basename from the file's path.  It ends with a slash if
   of nonzero length.  Note that this procedure also works for
   <stdin>, which is represented by the empty string.  */
static const char *
dir_name_of_file (_cpp_file *file)
{
  if (!file->dir_name)
    {
      size_t len = lbasename (file->path) - file->path;
      char *dir_name = XNEWVEC (char, len + 1);

      memcpy (dir_name, file->path, len);
      dir_name[len] = '\0';
      file->dir_name = dir_name;
    }

  return file->dir_name;
}

/* Handles #include-family directives (distinguished by TYPE),
   including HEADER, and the command line -imacros and -include.
   Returns true if a buffer was stacked.  */
bool
_cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
		    enum include_type type, location_t loc)
{
  /* For -include command-line flags we have type == IT_CMDLINE.
     When the first -include file is processed we have the case, where
     pfile->cur_token == pfile->cur_run->base, we are directly called up
     by the front end.  However in the case of the second -include file,
     we are called from _cpp_lex_token -> _cpp_get_fresh_line ->
     cpp_push_include, with pfile->cur_token != pfile->cur_run->base,
     and pfile->cur_token[-1].src_loc not (yet) initialized.
     However, when the include file cannot be found, we need src_loc to
     be initialized to some safe value: 0 means UNKNOWN_LOCATION.  */
  if (type == IT_CMDLINE && pfile->cur_token != pfile->cur_run->base)
    pfile->cur_token[-1].src_loc = 0;

  cpp_dir *dir = search_path_head (pfile, fname, angle_brackets, type);
  if (!dir)
    return false;

  _cpp_file *file = _cpp_find_file (pfile, fname, dir, angle_brackets,
				    type == IT_DEFAULT ? _cpp_FFK_PRE_INCLUDE
				    : _cpp_FFK_NORMAL, loc);
  if (type == IT_DEFAULT && file == NULL)
    return false;

  return _cpp_stack_file (pfile, file, type, loc);
}

/* NAME is a header file name, find the _cpp_file, if any.  */

static _cpp_file *
test_header_unit (cpp_reader *pfile, const char *name, bool angle,
		  location_t loc)
{
  if (cpp_dir *dir = search_path_head (pfile, name, angle, IT_INCLUDE))
    return _cpp_find_file (pfile, name, dir, angle, _cpp_FFK_NORMAL, loc);

  return nullptr;
}

/* NAME is a header file name, find the path we'll use to open it and infer that
   it is a header-unit.  */

const char *
_cpp_find_header_unit (cpp_reader *pfile, const char *name, bool angle,
		       location_t loc)
{
  if (_cpp_file *file = test_header_unit (pfile, name, angle, loc))
    {
      if (file->fd > 0)
	{
	  /* Don't leave it open.  */
	  close (file->fd);
	  file->fd = 0;
	}

      file->header_unit = +1;
      _cpp_mark_file_once_only (pfile, file);

      return file->path;
    }

  return nullptr;
}

/* NAME is a header file name, find the path we'll use to open it.  But do not
   infer it is a header unit.  */

const char *
cpp_probe_header_unit (cpp_reader *pfile, const char *name, bool angle,
		       location_t loc)
{
  if (_cpp_file *file = test_header_unit (pfile, name, angle, loc))
    return file->path;

  return nullptr;
}

/* Retrofit the just-entered main file asif it was an include.  This
   will permit correct include_next use, and mark it as a system
   header if that's where it resides.  We use filesystem-appropriate
   prefix matching of the include path to locate the main file.  */
void
cpp_retrofit_as_include (cpp_reader *pfile)
{
  /* We should be the outermost.  */
  gcc_assert (!pfile->buffer->prev);

  if (const char *name = pfile->main_file->name)
    {
      /* Locate name on the include dir path, using a prefix match.  */
      size_t name_len = strlen (name);
      for (cpp_dir *dir = pfile->quote_include; dir; dir = dir->next)
	if (dir->len < name_len
	    && IS_DIR_SEPARATOR (name[dir->len])
	    && !filename_ncmp (name, dir->name, dir->len))
	  {
	    pfile->main_file->dir = dir;
	    if (dir->sysp)
	      cpp_make_system_header (pfile, 1, 0);
	    break;
	  }
    }

  /* Initialize controlling macro state.  */
  pfile->mi_valid = true;
  pfile->mi_cmacro = 0;
}

/* Could not open FILE.  The complication is dependency output.  */
static void
open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets,
		  location_t loc)
{
  int sysp = pfile->line_table->highest_line > 1 && pfile->buffer ? pfile->buffer->sysp : 0;
  bool print_dep = CPP_OPTION (pfile, deps.style) > (angle_brackets || !!sysp);

  errno = file->err_no;
  if (print_dep && CPP_OPTION (pfile, deps.missing_files) && errno == ENOENT)
    {
      deps_add_dep (pfile->deps, file->name);
      /* If the preprocessor output (other than dependency information) is
         being used, we must also flag an error.  */
      if (CPP_OPTION (pfile, deps.need_preprocessor_output))
	cpp_errno_filename (pfile, CPP_DL_FATAL,
			    file->path ? file->path : file->name,
			    loc);
    }
  else
    {
      /* If we are not outputting dependencies, or if we are and dependencies
         were requested for this file, or if preprocessor output is needed
         in addition to dependency information, this is an error.

         Otherwise (outputting dependencies but not for this file, and not
         using the preprocessor output), we can still produce correct output
         so it's only a warning.  */
      if (CPP_OPTION (pfile, deps.style) == DEPS_NONE
          || print_dep
          || CPP_OPTION (pfile, deps.need_preprocessor_output))
	cpp_errno_filename (pfile, CPP_DL_FATAL,
			    file->path ? file->path : file->name,
			    loc);
      else
	cpp_errno_filename (pfile, CPP_DL_WARNING,
			    file->path ? file->path : file->name,
			    loc);
    }
}

/* Search in the chain beginning at HEAD for a file whose search path
   started at START_DIR != NULL.  */
static struct cpp_file_hash_entry *
search_cache (struct cpp_file_hash_entry *head, const cpp_dir *start_dir)
{
  while (head && head->start_dir != start_dir)
    head = head->next;

  return head;
}

/* Allocate a new _cpp_file structure.  */
static _cpp_file *
make_cpp_file (cpp_dir *dir, const char *fname)
{
  _cpp_file *file = XCNEW (_cpp_file);
  file->fd = -1;
  file->dir = dir;
  file->name = xstrdup (fname);

  return file;
}

/* Release a _cpp_file structure.  */
static void
destroy_cpp_file (_cpp_file *file)
{
  free ((void *) file->buffer_start);
  free ((void *) file->name);
  free ((void *) file->path);
  free (file);
}

/* Release all the files allocated by this reader.  */
static void
destroy_all_cpp_files (cpp_reader *pfile)
{
  _cpp_file *iter = pfile->all_files;
  while (iter)
    {
      _cpp_file *next = iter->next_file;
      destroy_cpp_file (iter);
      iter = next;
    }
}

/* A hash of directory names.  The directory names are the path names
   of files which contain a #include "", the included file name is
   appended to this directories.

   To avoid duplicate entries we follow the convention that all
   non-empty directory names should end in a '/'.  DIR_NAME must be
   stored in permanently allocated memory.  */
static cpp_dir *
make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp)
{
  struct cpp_file_hash_entry *entry, **hash_slot;
  cpp_dir *dir;

  hash_slot = (struct cpp_file_hash_entry **)
    htab_find_slot_with_hash (pfile->dir_hash, dir_name,
			      htab_hash_string (dir_name),
			      INSERT);

  /* Have we already hashed this directory?  */
  for (entry = *hash_slot; entry; entry = entry->next)
    if (entry->start_dir == NULL)
      return entry->u.dir;

  dir = XCNEW (cpp_dir);
  dir->next = pfile->quote_include;
  dir->name = (char *) dir_name;
  dir->len = strlen (dir_name);
  dir->sysp = sysp;
  dir->construct = 0;

  /* Store this new result in the hash table.  */
  entry = new_file_hash_entry (pfile);
  entry->next = *hash_slot;
  entry->start_dir = NULL;
  entry->location = pfile->line_table->highest_location;
  entry->u.dir = dir;
  *hash_slot = entry;

  return dir;
}

/* Create a new block of memory for file hash entries.  */
static void
allocate_file_hash_entries (cpp_reader *pfile)
{
  struct file_hash_entry_pool *pool = XNEW (struct file_hash_entry_pool);
  pool->file_hash_entries_used = 0;
  pool->next = pfile->file_hash_entries;
  pfile->file_hash_entries = pool;
}

/* Return a new file hash entry.  */
static struct cpp_file_hash_entry *
new_file_hash_entry (cpp_reader *pfile)
{
  unsigned int idx;
  if (pfile->file_hash_entries->file_hash_entries_used == FILE_HASH_POOL_SIZE)
    allocate_file_hash_entries (pfile);

  idx = pfile->file_hash_entries->file_hash_entries_used++;
  return &pfile->file_hash_entries->pool[idx];
}

/* Free the file hash entry pools.  */
static void
free_file_hash_entries (cpp_reader *pfile)
{
  struct file_hash_entry_pool *iter = pfile->file_hash_entries;
  while (iter)
    {
      struct file_hash_entry_pool *next = iter->next;
      free (iter);
      iter = next;
    }
}

/* Returns TRUE if a file FNAME has ever been successfully opened.
   This routine is not intended to correctly handle filenames aliased
   by links or redundant . or .. traversals etc.  */
bool
cpp_included (cpp_reader *pfile, const char *fname)
{
  struct cpp_file_hash_entry *entry;

  entry = (struct cpp_file_hash_entry *)
     htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname));

  while (entry && (entry->start_dir == NULL || entry->u.file->err_no))
    entry = entry->next;

  return entry != NULL;
}

/* Returns TRUE if a file FNAME has ever been successfully opened
   before LOCATION.  This routine is not intended to correctly handle
   filenames aliased by links or redundant . or .. traversals etc.  */
bool
cpp_included_before (cpp_reader *pfile, const char *fname,
		     location_t location)
{
  struct cpp_file_hash_entry *entry
    = (struct cpp_file_hash_entry *)
      htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname));

  if (IS_ADHOC_LOC (location))
    location = get_location_from_adhoc_loc (pfile->line_table, location);

  while (entry && (entry->start_dir == NULL || entry->u.file->err_no
		   || entry->location > location))
    entry = entry->next;

  return entry != NULL;
}

/* Calculate the hash value of a file hash entry P.  */

static hashval_t
file_hash_hash (const void *p)
{
  struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) p;
  const char *hname;
  if (entry->start_dir)
    hname = entry->u.file->name;
  else
    hname = entry->u.dir->name;

  return htab_hash_string (hname);
}

/* Compare a string Q against a file hash entry P.  */
static int
file_hash_eq (const void *p, const void *q)
{
  struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) p;
  const char *fname = (const char *) q;
  const char *hname;

  if (entry->start_dir)
    hname = entry->u.file->name;
  else
    hname = entry->u.dir->name;

  return filename_cmp (hname, fname) == 0;
}

/* Compare entries in the nonexistent file hash table.  These are just
   strings.  */
static int
nonexistent_file_hash_eq (const void *p, const void *q)
{
  return filename_cmp ((const char *) p, (const char *) q) == 0;
}

/* Initialize everything in this source file.  */
void
_cpp_init_files (cpp_reader *pfile)
{
  pfile->file_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
					NULL, xcalloc, free);
  pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
					NULL, xcalloc, free);
  allocate_file_hash_entries (pfile);
  pfile->nonexistent_file_hash = htab_create_alloc (127, htab_hash_string,
						    nonexistent_file_hash_eq,
						    NULL, xcalloc, free);
  obstack_specify_allocation (&pfile->nonexistent_file_ob, 0, 0,
			      xmalloc, free);
}

/* Finalize everything in this source file.  */
void
_cpp_cleanup_files (cpp_reader *pfile)
{
  htab_delete (pfile->file_hash);
  htab_delete (pfile->dir_hash);
  htab_delete (pfile->nonexistent_file_hash);
  obstack_free (&pfile->nonexistent_file_ob, 0);
  free_file_hash_entries (pfile);
  destroy_all_cpp_files (pfile);
}

/* Make the parser forget about files it has seen.  This can be useful
   for resetting the parser to start another run.  */
void
cpp_clear_file_cache (cpp_reader *pfile)
{
  _cpp_cleanup_files (pfile);
  pfile->file_hash_entries = NULL;
  pfile->all_files = NULL;
  _cpp_init_files (pfile);
}

/* Enter a file name in the hash for the sake of cpp_included.  */
void
_cpp_fake_include (cpp_reader *pfile, const char *fname)
{
  _cpp_find_file (pfile, fname, pfile->buffer->file->dir, 0, _cpp_FFK_FAKE, 0);
}

/* Not everyone who wants to set system-header-ness on a buffer can
   see the details of a buffer.  This is an exported interface because
   fix-header needs it.  */
void
cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc)
{
  int flags = 0;
  const class line_maps *line_table = pfile->line_table;
  const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
  /* 1 = system header, 2 = system header to be treated as C.  */
  if (syshdr)
    flags = 1 + (externc != 0);
  pfile->buffer->sysp = flags;
  _cpp_do_file_change (pfile, LC_RENAME, ORDINARY_MAP_FILE_NAME (map),
		       SOURCE_LINE (map, pfile->line_table->highest_line),
		       flags);
}

/* Allow the client to change the current file.  Used by the front end
   to achieve pseudo-file names like <built-in>.
   If REASON is LC_LEAVE, then NEW_NAME must be NULL.  */
void
cpp_change_file (cpp_reader *pfile, enum lc_reason reason,
		 const char *new_name)
{
  _cpp_do_file_change (pfile, reason, new_name, 1, 0);
}

struct report_missing_guard_data
{
  cpp_reader *pfile;
  const char **paths;
  size_t count;
};

/* Callback function for htab_traverse.  */
static int
report_missing_guard (void **slot, void *d)
{
  struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) *slot;
  struct report_missing_guard_data *data
    = (struct report_missing_guard_data *) d;

  /* Skip directories.  */
  if (entry->start_dir != NULL)
    {
      _cpp_file *file = entry->u.file;

      /* We don't want MI guard advice for the main file.  */
      if (!file->once_only
	  && file->cmacro == NULL
	  && file->stack_count == 1
	  && data->pfile->main_file != file)
	{
	  if (data->paths == NULL)
	    {
	      data->paths = XCNEWVEC (const char *, data->count);
	      data->count = 0;
	    }

	  data->paths[data->count++] = file->path;
	}
    }

  /* Keep traversing the hash table.  */
  return 1;
}

/* Comparison function for qsort.  */
static int
report_missing_guard_cmp (const void *p1, const void *p2)
{
  return strcmp (*(const char *const *) p1, *(const char *const *) p2);
}

/* Report on all files that might benefit from a multiple include guard.
   Triggered by -H.  */
void
_cpp_report_missing_guards (cpp_reader *pfile)
{
  struct report_missing_guard_data data;

  data.pfile = pfile;
  data.paths = NULL;
  data.count = htab_elements (pfile->file_hash);
  htab_traverse (pfile->file_hash, report_missing_guard, &data);

  if (data.paths != NULL)
    {
      size_t i;

      /* Sort the paths to avoid outputting them in hash table
	 order.  */
      qsort (data.paths, data.count, sizeof (const char *),
	     report_missing_guard_cmp);
      fputs (_("Multiple include guards may be useful for:\n"),
	     stderr);
      for (i = 0; i < data.count; i++)
	{
	  fputs (data.paths[i], stderr);
	  putc ('\n', stderr);
	}
      free (data.paths);
    }
}

/* Locate HEADER, and determine whether it is newer than the current
   file.  If it cannot be located or dated, return -1, if it is
   newer, return 1, otherwise 0.  */
int
_cpp_compare_file_date (cpp_reader *pfile, const char *fname,
			int angle_brackets)
{
  _cpp_file *file;
  struct cpp_dir *dir;

  dir = search_path_head (pfile, fname, angle_brackets, IT_INCLUDE);
  if (!dir)
    return -1;

  file = _cpp_find_file (pfile, fname, dir, angle_brackets, _cpp_FFK_NORMAL, 0);
  if (file->err_no)
    return -1;

  if (file->fd != -1)
    {
      close (file->fd);
      file->fd = -1;
    }

  return file->st.st_mtime > pfile->buffer->file->st.st_mtime;
}

/* Pushes the given file onto the buffer stack.  Returns nonzero if
   successful.  */
bool
cpp_push_include (cpp_reader *pfile, const char *fname)
{
  return _cpp_stack_include (pfile, fname, false, IT_CMDLINE,
			     pfile->line_table->highest_line);
}

/* Pushes the given file, implicitly included at the start of a
   compilation, onto the buffer stack but without any errors if the
   file is not found.  Returns nonzero if successful.  */
bool
cpp_push_default_include (cpp_reader *pfile, const char *fname)
{
  return _cpp_stack_include (pfile, fname, true, IT_DEFAULT,
			     pfile->line_table->highest_line);
}

/* Do appropriate cleanup when a file INC's buffer is popped off the
   input stack.  */
void
_cpp_pop_file_buffer (cpp_reader *pfile, _cpp_file *file,
		      const unsigned char *to_free)
{
  /* Record the inclusion-preventing macro, which could be NULL
     meaning no controlling macro.  */
  if (pfile->mi_valid && file->cmacro == NULL)
    file->cmacro = pfile->mi_cmacro;

  /* Invalidate control macros in the #including file.  */
  pfile->mi_valid = false;

  if (to_free)
    {
      if (to_free == file->buffer_start)
	{
	  file->buffer_start = NULL;
	  file->buffer = NULL;
	  file->buffer_valid = false;
	}
      free ((void *) to_free);
    }
}

/* Return the file name associated with FILE.  */
const char *
_cpp_get_file_name (_cpp_file *file)
{
  return file->name;
}

/* Inteface to file statistics record in _cpp_file structure. */
struct stat *
_cpp_get_file_stat (_cpp_file *file)
{
    return &file->st;
}

/* Set the include chain for "" to QUOTE, for <> to BRACKET.  If
   QUOTE_IGNORES_SOURCE_DIR, then "" includes do not look in the
   directory of the including file.

   If BRACKET does not lie in the QUOTE chain, it is set to QUOTE.  */
void
cpp_set_include_chains (cpp_reader *pfile, cpp_dir *quote, cpp_dir *bracket,
			int quote_ignores_source_dir)
{
  pfile->quote_include = quote;
  pfile->bracket_include = quote;
  pfile->quote_ignores_source_dir = quote_ignores_source_dir;

  for (; quote; quote = quote->next)
    {
      quote->name_map = NULL;
      quote->len = strlen (quote->name);
      if (quote == bracket)
	pfile->bracket_include = bracket;
    }
}

/* Append the file name to the directory to create the path, but don't
   turn / into // or // into ///; // may be a namespace escape.  */
static char *
append_file_to_dir (const char *fname, cpp_dir *dir)
{
  size_t dlen, flen;
  char *path;

  dlen = dir->len;
  flen = strlen (fname);
  path = XNEWVEC (char, dlen + 1 + flen + 1);
  memcpy (path, dir->name, dlen);
  if (dlen && !IS_DIR_SEPARATOR (path[dlen - 1]))
    path[dlen++] = '/';
  memcpy (&path[dlen], fname, flen + 1);

  return path;
}

/* Read a space delimited string of unlimited length from a stdio
   file F.  */
static char *
read_filename_string (int ch, FILE *f)
{
  char *alloc, *set;
  int len;

  len = 20;
  set = alloc = XNEWVEC (char, len + 1);
  if (! is_space (ch))
    {
      *set++ = ch;
      while ((ch = getc (f)) != EOF && ! is_space (ch))
	{
	  if (set - alloc == len)
	    {
	      len *= 2;
	      alloc = XRESIZEVEC (char, alloc, len + 1);
	      set = alloc + len / 2;
	    }
	  *set++ = ch;
	}
    }
  *set = '\0';
  ungetc (ch, f);
  return alloc;
}

/* Read the file name map file for DIR.  */
static void
read_name_map (cpp_dir *dir)
{
  static const char FILE_NAME_MAP_FILE[] = "header.gcc";
  char *name;
  FILE *f;
  size_t len, count = 0, room = 9;

  len = dir->len;
  name = (char *) alloca (len + sizeof (FILE_NAME_MAP_FILE) + 1);
  memcpy (name, dir->name, len);
  if (len && !IS_DIR_SEPARATOR (name[len - 1]))
    name[len++] = '/';
  strcpy (name + len, FILE_NAME_MAP_FILE);
  f = fopen (name, "r");

  dir->name_map = XNEWVEC (const char *, room);

  /* Silently return NULL if we cannot open.  */
  if (f)
    {
      int ch;

      while ((ch = getc (f)) != EOF)
	{
	  char *to;

	  if (is_space (ch))
	    continue;

	  if (count + 2 > room)
	    {
	      room += 8;
	      dir->name_map = XRESIZEVEC (const char *, dir->name_map, room);
	    }

	  dir->name_map[count] = read_filename_string (ch, f);
	  while ((ch = getc (f)) != EOF && is_hspace (ch))
	    ;

	  to = read_filename_string (ch, f);
	  if (IS_ABSOLUTE_PATH (to))
	    dir->name_map[count + 1] = to;
	  else
	    {
	      dir->name_map[count + 1] = append_file_to_dir (to, dir);
	      free (to);
	    }

	  count += 2;
	  while ((ch = getc (f)) != '\n')
	    if (ch == EOF)
	      break;
	}

      fclose (f);
    }

  /* Terminate the list of maps.  */
  dir->name_map[count] = NULL;
}

/* Remap a FILE's name based on the file_name_map, if any, for
   FILE->dir.  If the file name has any directory separators,
   recursively check those directories too.  */
static char *
remap_filename (cpp_reader *pfile, _cpp_file *file)
{
  const char *fname, *p;
  char *new_dir, *p3;
  cpp_dir *dir;
  size_t index, len;

  dir = file->dir;
  fname = file->name;

  for (;;)
    {
      if (!dir->name_map)
	read_name_map (dir);

      for (index = 0; dir->name_map[index]; index += 2)
	if (!filename_cmp (dir->name_map[index], fname))
	    return xstrdup (dir->name_map[index + 1]);
      if (IS_ABSOLUTE_PATH (fname))
	return NULL;
      p = strchr (fname, '/');
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
      {
	const char *p2 = strchr (fname, '\\');
	if (!p || (p > p2))
	  p = p2;
      }
#endif
      if (!p || p == fname)
	return NULL;

      len = dir->len + (p - fname + 1);
      new_dir = XNEWVEC (char, len + 2);
      p3 = new_dir + dir->len;
      memcpy (new_dir, dir->name, dir->len);
      if (dir->len && !IS_DIR_SEPARATOR (dir->name[dir->len - 1]))
	{
	  *p3++ = '/';
	  len++;
	}
      memcpy (p3, fname, p - fname + 1);
      new_dir[len] = '\0';

      dir = make_cpp_dir (pfile, new_dir, dir->sysp);
      fname = p + 1;
    }
}

/* Returns true if PCHNAME is a valid PCH file for FILE.  */
static bool
validate_pch (cpp_reader *pfile, _cpp_file *file, const char *pchname)
{
  const char *saved_path = file->path;
  bool valid = false;

  file->path = pchname;
  if (open_file (file))
    {
      valid = 1 & pfile->cb.valid_pch (pfile, pchname, file->fd);

      if (!valid)
	{
	  close (file->fd);
	  file->fd = -1;
	}

      if (CPP_OPTION (pfile, print_include_names))
	{
	  unsigned int i;
	  for (i = 1; i < pfile->line_table->depth; i++)
	    putc ('.', stderr);
	  fprintf (stderr, "%c %s\n",
		   valid ? '!' : 'x', pchname);
	}
    }

  file->path = saved_path;
  return valid;
}

/* Get the path associated with the _cpp_file F.  The path includes
   the base name from the include directive and the directory it was
   found in via the search path.  */

const char *
cpp_get_path (struct _cpp_file *f)
{
  return f->path;
}

/* Get the directory associated with the _cpp_file F.  */

cpp_dir *
cpp_get_dir (struct _cpp_file *f)
{
  return f->dir;
}

/* Get the cpp_buffer currently associated with the cpp_reader
   PFILE.  */

cpp_buffer *
cpp_get_buffer (cpp_reader *pfile)
{
  return pfile->buffer;
}

/* Get the _cpp_file associated with the cpp_buffer B.  */

_cpp_file *
cpp_get_file (cpp_buffer *b)
{
  return b->file;
}

/* Get the previous cpp_buffer given a cpp_buffer B.  The previous
   buffer is the buffer that included the given buffer.  */

cpp_buffer *
cpp_get_prev (cpp_buffer *b)
{
  return b->prev;
}

/* This data structure holds the list of header files that were seen
   while the PCH was being built.  The 'entries' field is kept sorted
   in memcmp() order; yes, this means that on little-endian systems,
   it's sorted initially by the least-significant byte of 'size', but
   that's OK.  The code does rely on having entries with the same size
   next to each other.  */

struct pchf_entry {
  /* The size of this file.  This is used to save running a MD5 checksum
     if the sizes don't match.  */
  off_t size;
  /* The MD5 checksum of this file.  */
  unsigned char sum[16];
  /* Is this file to be included only once?  */
  bool once_only;
};

struct pchf_data {
  /* Number of pchf_entry structures.  */
  size_t count;

  /* Are there any values with once_only set?
     This is used as an optimisation, it means we don't have to search
     the structure if we're processing a regular #include.  */
  bool have_once_only;

  struct pchf_entry entries[1];
};

static struct pchf_data *pchf;

/* A qsort ordering function for pchf_entry structures.  */

static int
pchf_save_compare (const void *e1, const void *e2)
{
  return memcmp (e1, e2, sizeof (struct pchf_entry));
}

/* Create and write to F a pchf_data structure.  */

bool
_cpp_save_file_entries (cpp_reader *pfile, FILE *fp)
{
  size_t count = 0;
  struct pchf_data *result;
  size_t result_size;
  _cpp_file *f;
  bool ret;

  for (f = pfile->all_files; f; f = f->next_file)
    ++count;

  result_size = (sizeof (struct pchf_data)
		 + sizeof (struct pchf_entry) * (count - 1));
  result = XCNEWVAR (struct pchf_data, result_size);

  result->count = 0;
  result->have_once_only = false;

  for (f = pfile->all_files; f; f = f->next_file)
    {
      size_t count;

      /* This should probably never happen, since if a read error occurred
	 the PCH file shouldn't be written...  */
      if (f->dont_read || f->err_no)
	continue;

      if (f->stack_count == 0)
	continue;

      count = result->count++;

      result->entries[count].once_only = f->once_only;
      /* |= is avoided in the next line because of an HP C compiler bug */
      result->have_once_only = result->have_once_only | f->once_only;
      if (f->buffer_valid)
	md5_buffer ((const char *)f->buffer,
		    f->st.st_size, result->entries[count].sum);
      else
	{
	  FILE *ff;
	  int oldfd = f->fd;

	  if (!open_file (f))
	    {
	      open_file_failed (pfile, f, 0, 0);
	      free (result);
	      return false;
	    }
	  ff = fdopen (f->fd, "rb");
	  md5_stream (ff, result->entries[count].sum);
	  fclose (ff);
	  f->fd = oldfd;
	}
      result->entries[count].size = f->st.st_size;
    }

  result_size = (sizeof (struct pchf_data)
                 + sizeof (struct pchf_entry) * (result->count - 1));

  qsort (result->entries, result->count, sizeof (struct pchf_entry),
	 pchf_save_compare);

  ret = fwrite (result, result_size, 1, fp) == 1;
  free (result);
  return ret;
}

/* Read the pchf_data structure from F.  */

bool
_cpp_read_file_entries (cpp_reader *pfile ATTRIBUTE_UNUSED, FILE *f)
{
  struct pchf_data d;

  if (fread (&d, sizeof (struct pchf_data) - sizeof (struct pchf_entry), 1, f)
       != 1)
    return false;

  pchf = XNEWVAR (struct pchf_data, sizeof (struct pchf_data)
		  + sizeof (struct pchf_entry) * (d.count - 1));
  memcpy (pchf, &d, sizeof (struct pchf_data) - sizeof (struct pchf_entry));
  if (fread (pchf->entries, sizeof (struct pchf_entry), d.count, f)
      != d.count)
    return false;
  return true;
}

/* The parameters for pchf_compare.  */

struct pchf_compare_data
{
  /* The size of the file we're looking for.  */
  off_t size;

  /* The MD5 checksum of the file, if it's been computed.  */
  unsigned char sum[16];

  /* Is SUM valid?  */
  bool sum_computed;

  /* Do we need to worry about entries that don't have ONCE_ONLY set?  */
  bool check_included;

  /* The file that we're searching for.  */
  _cpp_file *f;
};

/* bsearch comparison function; look for D_P in E_P.  */

static int
pchf_compare (const void *d_p, const void *e_p)
{
  const struct pchf_entry *e = (const struct pchf_entry *)e_p;
  struct pchf_compare_data *d = (struct pchf_compare_data *)d_p;
  int result;

  result = memcmp (&d->size, &e->size, sizeof (off_t));
  if (result != 0)
    return result;

  if (! d->sum_computed)
    {
      _cpp_file *const f = d->f;

      md5_buffer ((const char *)f->buffer, f->st.st_size, d->sum);
      d->sum_computed = true;
    }

  result = memcmp (d->sum, e->sum, 16);
  if (result != 0)
    return result;

  if (d->check_included || e->once_only)
    return 0;
  else
    return 1;
}

/* Check that F is not in a list read from a PCH file (if any).
   Assumes that f->buffer_valid is true.  Return TRUE if the file
   should not be read.  */

static bool
check_file_against_entries (cpp_reader *pfile ATTRIBUTE_UNUSED,
			    _cpp_file *f,
			    bool check_included)
{
  struct pchf_compare_data d;

  if (pchf == NULL
      || (! check_included && ! pchf->have_once_only))
    return false;

  d.size = f->st.st_size;
  d.sum_computed = false;
  d.f = f;
  d.check_included = check_included;
  return bsearch (&d, pchf->entries, pchf->count, sizeof (struct pchf_entry),
		  pchf_compare) != NULL;
}

/* Return true if the file FNAME is found in the appropriate include file path
   as indicated by ANGLE_BRACKETS.  */

bool
_cpp_has_header (cpp_reader *pfile, const char *fname, int angle_brackets,
		 enum include_type type)
{
  cpp_dir *start_dir = search_path_head (pfile, fname, angle_brackets, type);
  _cpp_file *file = _cpp_find_file (pfile, fname, start_dir, angle_brackets,
				    _cpp_FFK_HAS_INCLUDE, 0);
  return file->err_no != ENOENT;
}

/* Read a file and convert to input charset, the same as if it were being read
   by a cpp_reader.  */

cpp_converted_source
cpp_get_converted_source (const char *fname, const char *input_charset)
{
  cpp_converted_source res = {};
  _cpp_file file = {};
  file.fd = -1;
  file.name = lbasename (fname);
  file.path = fname;
  if (!open_file (&file))
    return res;
  const bool ok = read_file_guts (NULL, &file, 0, input_charset);
  close (file.fd);
  if (!ok)
    return res;
  res.to_free = (char *) file.buffer_start;
  res.data = (char *) file.buffer;
  res.len = file.st.st_size;
  return res;
}
