/* Part of CPP library.  File handling.
   Copyright (C) 1986-2026 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;

  /* Size for #embed, perhaps smaller than st.st_size.  */
  size_t limit;

  /* Offset for #embed.  */
  off_t offset;

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

  /* Set if a header wasn't found with __has_include or __has_include_next
     and error should be emitted if it is included normally.  */
  bool deferred_error : 1;

  /* File loaded from #embed.  */
  bool embed : 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 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,
						 bool is_embed);
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);
static void _cpp_post_stack_file (cpp_reader *, _cpp_file *, include_type, 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 (!file->embed && 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;
  bool saw_embed_include = false;
  struct cpp_dir *found_in_cache = NULL;
  bool is_embed = kind == _cpp_FFK_EMBED || kind == _cpp_FFK_HAS_EMBED;

  /* 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,
		    is_embed);
  if (entry)
    {
      if (entry->u.file->deferred_error
	  && (kind == _cpp_FFK_NORMAL || kind == _cpp_FFK_EMBED))
	{
	  open_file_failed (pfile, entry->u.file, angle_brackets, loc);
	  entry->u.file->deferred_error = false;
	}
      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));
  file->embed = is_embed;

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

	if (is_embed
	    && file->dir == start_dir
	    && start_dir != pfile->embed_include
	    && start_dir != &pfile->no_search_path)
	  file->dir = pfile->embed_include;
	else
	  file->dir = file->dir->next;
	if (file->dir == NULL)
	  {
	    if (!is_embed
		&& 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
		       of use, so need to remove the newly created entry.
		       htab_clear_slot requires that it is non-NULL, so
		       store some non-NULL but valid pointer there,
		       htab_clear_slot will immediately overwrite it.  */
		    *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 = &hash_slot;
		    htab_clear_slot (pfile->file_hash, hash_slot);
		  }
		return NULL;
	      }

	    if (kind != _cpp_FFK_HAS_INCLUDE && kind != _cpp_FFK_HAS_EMBED)
	      open_file_failed (pfile, file, angle_brackets, loc);
	    else
	      file->deferred_error = true;
	    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 if (file->dir == pfile->embed_include)
	  saw_embed_include = true;
	else
	  continue;

	entry
	  = search_cache ((struct cpp_file_hash_entry *) *hash_slot,
			  file->dir, is_embed);
	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;
    }
  if (saw_embed_include
      && pfile->embed_include != start_dir
      && found_in_cache != pfile->embed_include)
    {
      entry = new_file_hash_entry (pfile);
      entry->next = (struct cpp_file_hash_entry *) *hash_slot;
      entry->start_dir = pfile->embed_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, pad, 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;

  pad = CPP_BUFFER_PADDING;
  /* The '+ PAD' here is space for the final '\n' and PAD-1 bytes of padding,
     allowing search_line_fast to use (possibly misaligned) vector loads.  */
  buf = XNEWVEC (uchar, size + pad);
  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 + pad);
	}
    }

  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 + pad, 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 (f->embed)
	continue;

      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)
{
  int sysp = 0;

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

  _cpp_post_stack_file (pfile, file, type, sysp);
  return true;
}

/* Like _cpp_stack_file, but for a file that's been replaced by the contents of
   BUF.  Used for C++ modules include -> import translation.  */

static bool
_cpp_stack_translated_file (cpp_reader *pfile, _cpp_file *file,
			    char *buf, include_type type)
{
  /* 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.  */
  if (type != IT_CMDLINE)
    {
      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;
  if (type == IT_CMDLINE)
    /* Tell _cpp_pop_buffer to change files.  */
    buffer->file = file;

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

  _cpp_post_stack_file (pfile, file, type, false);
  return true;
}

/* The common epilogue of _cpp_stack_file and _cpp_stack_translated_file.  */

static void
_cpp_post_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
		      bool sysp)
{
  /* 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--;

  /* Normally a header unit becomes an __import directive in the current file,
     but with -include we need something to LC_LEAVE to trigger the file_change
     hook and continue to the next -include or the main source file.  */
  if (file->header_unit <= 0 || type == IT_CMDLINE)
    /* 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);
    }
}

/* 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.  */
struct cpp_dir *
search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets,
		  enum include_type type, bool suppress_diagnostic)
{
  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 = type == IT_EMBED ? pfile->embed_include : 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 && type != IT_EMBED)
    dir = pfile->quote_include;
  else
    return make_cpp_dir (pfile, dir_name_of_file (file),
			 pfile->buffer ? pfile->buffer->sysp : 0);

  if (dir == NULL && !suppress_diagnostic)
    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;

  if (is_known_idempotent_file (pfile, file, type == IT_IMPORT))
    return false;

  /* Check C++ module include translation.  */
  char *buf = nullptr;
  if (!file->header_unit && type < IT_DEFAULT
      /* Do not include translate include-next.  */
      && type != IT_INCLUDE_NEXT
      && pfile->cb.translate_include)
    {
      const char *aname = nullptr;
      buf = (pfile->cb.translate_include
	     (pfile, pfile->line_table, loc, file,
	      angle_brackets, &aname));
      if (!buf && aname)
	{
	  _cpp_file *afile = _cpp_find_file (pfile, aname, dir, angle_brackets,
					     _cpp_FFK_NORMAL, loc);
	  if (afile && !afile->header_unit)
	    buf = (pfile->cb.translate_include
		   (pfile, pfile->line_table, loc,
		    afile, angle_brackets, nullptr));
	  if (buf)
	    file = afile;
	}
    }

  if (buf)
    return _cpp_stack_translated_file (pfile, file, buf, type);
  else
    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;
}

/* Helper function for _cpp_stack_embed.  Finish #embed/__has_embed processing
   after a file is found and data loaded into buffer.  */

static int
finish_embed (cpp_reader *pfile, _cpp_file *file,
	      struct cpp_embed_params *params)
{
  const uchar *buffer = file->buffer;
  size_t limit = file->limit;
  if (params->offset - file->offset > limit)
    limit = 0;
  else
    {
      buffer += params->offset - file->offset;
      limit -= params->offset - file->offset;
    }
  if (params->limit < limit)
    limit = params->limit;

  size_t embed_tokens = 0;
  if (CPP_OPTION (pfile, lang) != CLK_ASM
      && limit >= 64)
    embed_tokens = ((limit - 2) / INT_MAX) + (((limit - 2) % INT_MAX) != 0);

  size_t max = INTTYPE_MAXIMUM (size_t) / sizeof (cpp_token);
  if ((embed_tokens ? (embed_tokens > (max - 3) / 2) : (limit > max / 2))
      || (limit
	  ? (params->prefix.count > max
	     || params->suffix.count > max
	     || ((embed_tokens ? embed_tokens * 2 + 3 : limit * 2 - 1)
		 + params->prefix.count
		 + params->suffix.count > max))
	  : params->if_empty.count > max))
    {
      cpp_error_at (pfile, CPP_DL_ERROR, params->loc,
		    "%s is too large", file->path);
      return 0;
    }

  size_t len = 0;
  for (size_t i = 0; i < limit; ++i)
    {
      if (buffer[i] < 10)
	len += 2;
      else if (buffer[i] < 100)
	len += 3;
#if UCHAR_MAX == 255
      else
	len += 4;
#else
      else if (buffer[i] < 1000)
	len += 4;
      else
	{
	  char buf[64];
	  len += sprintf (buf, "%d", buffer[i]) + 1;
	}
#endif
      if (len > INTTYPE_MAXIMUM (ssize_t))
	{
	  cpp_error_at (pfile, CPP_DL_ERROR, params->loc,
			"%s is too large", file->path);
	  return 0;
	}
      if (embed_tokens && i == 0)
	i = limit - 2;
    }
  uchar *s = len ? _cpp_unaligned_alloc (pfile, len) : NULL;
  _cpp_buff *tok_buff = NULL;
  cpp_token *tok = &pfile->directive_result, *toks = tok;
  size_t count = 0;
  if (limit)
    count = (params->prefix.count
	     + (embed_tokens ? embed_tokens * 2 + 3 : limit * 2 - 1)
	     + params->suffix.count) - 1;
  else if (params->if_empty.count)
    count = params->if_empty.count - 1;
  if (count)
    {
      tok_buff = _cpp_get_buff (pfile, count * sizeof (cpp_token));
      toks = (cpp_token *) tok_buff->base;
    }
  cpp_embed_params_tokens *prefix
    = limit ? &params->prefix : &params->if_empty;
  if (prefix->count)
    {
      *tok = *prefix->base_run.base;
      tok = toks;
      tokenrun *cur_run = &prefix->base_run;
      while (cur_run)
	{
	  size_t cnt = (cur_run->next ? cur_run->limit
			: prefix->cur_token) - cur_run->base;
	  cpp_token *t = cur_run->base;
	  if (cur_run == &prefix->base_run)
	    {
	      t++;
	      cnt--;
	    }
	  memcpy (tok, t, cnt * sizeof (cpp_token));
	  tok += cnt;
	  cur_run = cur_run->next;
	}
    }
  for (size_t i = 0; i < limit; ++i)
    {
      tok->src_loc = params->loc;
      tok->type = CPP_NUMBER;
      tok->flags = NO_EXPAND;
      if (i == 0)
	tok->flags |= PREV_WHITE;
      tok->val.str.text = s;
      tok->val.str.len = sprintf ((char *) s, "%d", buffer[i]);
      s += tok->val.str.len + 1;
      if (tok == &pfile->directive_result)
	tok = toks;
      else
	tok++;
      if (i < limit - 1)
	{
	  tok->src_loc = params->loc;
	  tok->type = CPP_COMMA;
	  tok->flags = NO_EXPAND;
	  tok++;
	}
      if (i == 0 && embed_tokens)
	{
	  ++i;
	  for (size_t j = 0; j < embed_tokens; ++j)
	    {
	      tok->src_loc = params->loc;
	      tok->type = CPP_EMBED;
	      tok->flags = NO_EXPAND;
	      tok->val.str.text = &buffer[i];
	      tok->val.str.len
		= limit - 1 - i > INT_MAX ? INT_MAX : limit - 1 - i;
	      i += tok->val.str.len;
	      if (tok->val.str.len < 32 && j)
		{
		  /* Avoid CPP_EMBED with a fewer than 32 bytes, shrink the
		     previous CPP_EMBED by 64 and grow this one by 64.  */
		  tok[-2].val.str.len -= 64;
		  tok->val.str.text -= 64;
		  tok->val.str.len += 64;
		}
	      tok++;
	      tok->src_loc = params->loc;
	      tok->type = CPP_COMMA;
	      tok->flags = NO_EXPAND;
	      tok++;
	    }
	  --i;
	}
    }
  if (limit && params->suffix.count)
    {
      tokenrun *cur_run = &params->suffix.base_run;
      cpp_token *orig_tok = tok;
      while (cur_run)
	{
	  size_t cnt = (cur_run->next ? cur_run->limit
			: params->suffix.cur_token) - cur_run->base;
	  cpp_token *t = cur_run->base;
	  memcpy (tok, t, cnt * sizeof (cpp_token));
	  tok += cnt;
	  cur_run = cur_run->next;
	}
      orig_tok->flags |= PREV_WHITE;
    }
  pfile->directive_result.flags |= PREV_WHITE;
  if (count)
    {
      _cpp_push_token_context (pfile, NULL, toks, count);
      pfile->context->buff = tok_buff;
    }
  return limit ? 1 : 2;
}

/* Helper function for initialization of base64_dec table.
   Can't rely on ASCII compatibility, so check each letter
   separately.  */

constexpr signed char
base64_dec_fn (unsigned char c)
{
  return (c == 'A' ? 0 : c == 'B' ? 1 : c == 'C' ? 2 : c == 'D' ? 3
	  : c == 'E' ? 4 : c == 'F' ? 5 : c == 'G' ? 6 : c == 'H' ? 7
	  : c == 'I' ? 8 : c == 'J' ? 9 : c == 'K' ? 10 : c == 'L' ? 11
	  : c == 'M' ? 12 : c == 'N' ? 13 : c == 'O' ? 14 : c == 'P' ? 15
	  : c == 'Q' ? 16 : c == 'R' ? 17 : c == 'S' ? 18 : c == 'T' ? 19
	  : c == 'U' ? 20 : c == 'V' ? 21 : c == 'W' ? 22 : c == 'X' ? 23
	  : c == 'Y' ? 24 : c == 'Z' ? 25
	  : c == 'a' ? 26 : c == 'b' ? 27 : c == 'c' ? 28 : c == 'd' ? 29
	  : c == 'e' ? 30 : c == 'f' ? 31 : c == 'g' ? 32 : c == 'h' ? 33
	  : c == 'i' ? 34 : c == 'j' ? 35 : c == 'k' ? 36 : c == 'l' ? 37
	  : c == 'm' ? 38 : c == 'n' ? 39 : c == 'o' ? 40 : c == 'p' ? 41
	  : c == 'q' ? 42 : c == 'r' ? 43 : c == 's' ? 44 : c == 't' ? 45
	  : c == 'u' ? 46 : c == 'v' ? 47 : c == 'w' ? 48 : c == 'x' ? 49
	  : c == 'y' ? 50 : c == 'z' ? 51
	  : c == '0' ? 52 : c == '1' ? 53 : c == '2' ? 54 : c == '3' ? 55
	  : c == '4' ? 56 : c == '5' ? 57 : c == '6' ? 58 : c == '7' ? 59
	  : c == '8' ? 60 : c == '9' ? 61 : c == '+' ? 62 : c == '/' ? 63
	  : -1);
}

/* base64 decoding table.  */

static constexpr signed char base64_dec[] = {
#define B64D0(x) base64_dec_fn (x)
#define B64D1(x) B64D0 (x), B64D0 (x + 1), B64D0 (x + 2), B64D0 (x + 3)
#define B64D2(x) B64D1 (x), B64D1 (x + 4), B64D1 (x + 8), B64D1 (x + 12)
#define B64D3(x) B64D2 (x), B64D2 (x + 16), B64D2 (x + 32), B64D2 (x + 48)
  B64D3 (0), B64D3 (64), B64D3 (128), B64D3 (192)
};

/* Helper function for _cpp_stack_embed.  Handle #embed/__has_embed with
   gnu::base64 parameter.  */

static int
finish_base64_embed (cpp_reader *pfile, const char *fname, bool angle,
		     struct cpp_embed_params *params)
{
  size_t len, end, i, j, base64_len = 0, cnt;
  uchar *buf = NULL, *q, pbuf[4], qbuf[3];
  const uchar *base64_str;
  if (angle || strcmp (fname, "."))
    {
      if (!params->has_embed)
	cpp_error_at (pfile, CPP_DL_ERROR, params->loc,
		      "%<gnu::base64%> parameter can be only used with "
		      "%<\".\"%>");
      return 0;
    }
  tokenrun *cur_run = &params->base64.base_run;
  cpp_token *tend, *tok;
  while (cur_run)
    {
      tend = cur_run->next ? cur_run->limit : params->base64.cur_token;
      for (tok = cur_run->base; tok < tend; ++tok)
	{
	  if (tok->val.str.len < 2
	      || tok->val.str.text[0] != '"'
	      || tok->val.str.text[tok->val.str.len - 1] != '"')
	    {
	    fail:
	      cpp_error_at (pfile, CPP_DL_ERROR, params->loc,
			    "%<gnu::base64%> argument not valid base64 "
			    "encoded string");
	      free (buf);
	      return 0;
	    }
	  if (tok->val.str.len - 2 > (~(size_t) 0) - base64_len)
	    goto fail;
	  base64_len += tok->val.str.len - 2;
	}
      cur_run = cur_run->next;
    }
  if ((base64_len & 3) != 0)
    goto fail;
  len = base64_len / 4 * 3;
  end = len;

  if (params->has_embed)
    q = qbuf;
  else
    {
      buf = XNEWVEC (uchar, len ? len : 1);
      q = buf;
    }
  cur_run = &params->base64.base_run;
  tend = cur_run->next ? cur_run->limit : params->base64.cur_token;
  tok = cur_run->base;
  base64_str = tok->val.str.text + 1;
  cnt = tok->val.str.len - 2;
  ++tok;
  for (i = 0; i < end; i += 3)
    {
      for (j = 0; j < 4; ++j)
	{
	  while (cnt == 0)
	    {
	      if (tok == tend)
		{
		  cur_run = cur_run->next;
		  tend = (cur_run->next ? cur_run->limit
			  : params->base64.cur_token);
		  tok = cur_run->base;
		}
	      base64_str = tok->val.str.text + 1;
	      cnt = tok->val.str.len - 2;
	      ++tok;
	    }
	  pbuf[j] = *base64_str;
	  base64_str++;
	  --cnt;
	}
      if (pbuf[3] == '=' && i + 3 >= end)
	{
	  end = len - 3;
	  --len;
	  if (pbuf[2] == '=')
	    --len;
	  break;
	}
      int a = base64_dec[pbuf[0]];
      int b = base64_dec[pbuf[1]];
      int c = base64_dec[pbuf[2]];
      int d = base64_dec[pbuf[3]];
      if (a == -1 || b == -1 || c == -1 || d == -1)
	goto fail;
      q[0] = (a << 2) | (b >> 4);
      q[1] = (b << 4) | (c >> 2);
      q[2] = (c << 6) | d;
      if (!params->has_embed)
	q += 3;
    }
  if (len != end)
    {
      int a = base64_dec[pbuf[0]];
      int b = base64_dec[pbuf[1]];
      if (a == -1 || b == -1)
	goto fail;
      q[0] = (a << 2) | (b >> 4);
      if (len - end == 2)
	{
	  int c = base64_dec[pbuf[2]];
	  if (c == -1)
	    goto fail;
	  q[1] = (b << 4) | (c >> 2);
	  if ((c & 3) != 0)
	    goto fail;
	}
      else if ((b & 15) != 0)
	goto fail;
    }
  if (params->has_embed)
    return len ? 1 : 2;
  _cpp_file *file = make_cpp_file (NULL, "");
  file->embed = 1;
  file->next_file = pfile->all_files;
  pfile->all_files = file;
  params->limit = -1;
  params->offset = 0;
  file->limit = len;
  file->buffer = buf;
  file->path = xstrdup ("<base64>");
  return finish_embed (pfile, file, params);
}

/* Try to load FNAME with #embed/__has_embed parameters PARAMS.
   If !PARAMS->has_embed, return new token in pfile->directive_result
   (first token) and rest in a pushed non-macro context.
   Returns 0 for not found/errors, 1 for non-empty resource and 2
   for empty resource.  */

int
_cpp_stack_embed (cpp_reader *pfile, const char *fname, bool angle,
		  struct cpp_embed_params *params)
{
  if (params->base64.count)
    return finish_base64_embed (pfile, fname, angle, params);
  cpp_dir *dir = search_path_head (pfile, fname, angle, IT_EMBED,
				   params->has_embed);
  if (!dir)
    return 0;
  _cpp_file *file = _cpp_find_file (pfile, fname, dir, angle,
				    params->has_embed
				    ? _cpp_FFK_HAS_EMBED : _cpp_FFK_EMBED,
				    params->loc);
  if (!file)
    return 0;
  if (file->dont_read || file->err_no)
    return 0;
  _cpp_file *orig_file = file;
  if (file->buffer_valid
      && (!S_ISREG (file->st.st_mode)
	  || file->offset + (cpp_num_part) 0 > params->offset
	  || (file->limit < file->st.st_size - file->offset + (size_t) 0
	      && (params->offset - file->offset > (cpp_num_part) file->limit
		  || file->limit - (params->offset
				    - file->offset) < params->limit))))
    {
      bool found = false;
      if (S_ISREG (file->st.st_mode))
	{
	  while (file->next_file
		 && file->next_file->embed
		 && file->next_file->buffer_valid
		 && file->next_file->dir == file->dir
		 && strcmp (file->name, file->next_file->name) == 0
		 && strcmp (file->path, file->next_file->path) == 0)
	    {
	      file = file->next_file;
	      if (file->offset + (cpp_num_part) 0 <= params->offset
		  && (file->limit >= (file->st.st_size - file->offset
				      + (size_t) 0)
		      || (params->offset
			  - file->offset <= (cpp_num_part) file->limit
			  && file->limit - (params->offset
					    - file->offset) >= params->limit)))
		{
		  found = true;
		  break;
		}
	    }
	}
      if (!found)
	{
	  _cpp_file *file2 = make_cpp_file (file->dir, file->name);
	  file2->path = xstrdup (file->path);
	  file2->next_file = file->next_file;
	  file2->embed = true;
	  file->next_file = file2;
	  file = file2;
	}
    }
  if (!file->buffer_valid)
    {
      if (file->fd == -1 && !open_file (file))
	{
	  if (params->has_embed)
	    file->deferred_error = true;
	  else
	    open_file_failed (pfile, file, 0, params->loc);
	  return 0;
	}
      if (S_ISBLK (file->st.st_mode))
	{
	  if (params->has_embed)
	    {
	      close (file->fd);
	      file->fd = -1;
	      return 0;
	    }
	  cpp_error_at (pfile, CPP_DL_ERROR, params->loc,
			"%s is a block device", file->path);
	fail:
	  close (file->fd);
	  file->fd = -1;
	  file->dont_read = true;
	  return 0;
	}

      if (CPP_OPTION (pfile, deps.style)
	  && !params->has_embed
	  && file == orig_file
	  && file->path[0])
	deps_add_dep (pfile->deps, file->path);

      bool regular = S_ISREG (file->st.st_mode) != 0;
      ssize_t size, total, count;
      uchar *buf;
      if (regular)
	{
	  cpp_num_part limit;
	  if (file->st.st_size + (cpp_num_part) 0 < params->offset)
	    limit = 0;
	  else if (file->st.st_size - params->offset < params->limit)
	    limit = file->st.st_size - params->offset;
	  else
	    limit = params->limit;
	  if (params->has_embed)
	    return limit != 0 ? 1 : 2;
	  if (limit > INTTYPE_MAXIMUM (ssize_t))
	    {
	      cpp_error_at (pfile, CPP_DL_ERROR, params->loc,
			    "%s is too large", file->path);
	      goto fail;
	    }
	  if (lseek (file->fd, params->offset, SEEK_CUR)
	      != (off_t) params->offset)
	    {
	      cpp_errno_filename (pfile, CPP_DL_ERROR, file->path,
				  params->loc);
	      goto fail;
	    }
	  file->offset = params->offset;
	  file->limit = limit;
	  size = limit;
	}
      else if (params->has_embed)
	return 2;
      else if (params->limit > 8 * 1024)
	size = 8 * 1024;
      else
	size = params->limit;
      buf = XNEWVEC (uchar, size ? size : 1);
      total = 0;

      if (!regular && params->offset)
	{
	  uchar *buf2 = buf;
	  ssize_t size2 = size;
	  cpp_num_part total2 = params->offset;

	  if (params->offset > 8 * 1024 && size < 8 * 1024)
	    {
	      size2 = 32 * 1024;
	      buf2 = XNEWVEC (uchar, size2);
	    }
	  do
	    {
	      if ((cpp_num_part) size2 > total2)
		size2 = total2;
	      count = read (file->fd, buf2, size2);
	      if (count < 0)
		{
		  cpp_errno_filename (pfile, CPP_DL_ERROR, file->path,
				      params->loc);
		  if (buf2 != buf)
		    free (buf2);
		  free (buf);
		  goto fail;
		}
	      total2 -= count;
	    }
	  while (total2);
	  if (buf2 != buf)
	    free (buf2);
	}

      while ((count = read (file->fd, buf + total, size - total)) > 0)
	{
	  total += count;
	  if (total == size)
	    {
	      if (regular || size + (cpp_num_part) 0 == params->limit)
		break;
	      size = (size_t) size * 2;
	      if (size < 0)
		{
		  if (params->limit <= INTTYPE_MAXIMUM (ssize_t))
		    size = params->limit;
		  else
		    {
		      cpp_error_at (pfile, CPP_DL_ERROR, params->loc,
				    "%s is too large", file->path);
		      free (buf);
		      goto fail;
		    }
		}
	      else if (size + (cpp_num_part) 0 > params->limit)
		size = params->limit;
	      buf = XRESIZEVEC (uchar, buf, size);
	    }
	}

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

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

      file->buffer_start = buf;
      file->buffer = buf;
      file->buffer_valid = 1;
      close (file->fd);
      file->fd = -1;
    }
  else if (params->has_embed)
    {
      if (params->offset - file->offset > file->limit)
	return 2;
      size_t limit = file->limit - (params->offset - file->offset);
      return limit && params->limit ? 1 : 2;
    }

  return finish_embed (pfile, file, params);
}

/* 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,
	      bool is_embed)
{
  while (head && (head->start_dir != start_dir
		  || head->u.file->embed != is_embed))
    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)
{
  /* It does not matter what are the contents of fake_source_dir, it will never
     be inspected; we just use its address to uniquely signify that this file
     was added as a fake include, so a later call to _cpp_find_file (to include
     the file for real) won't find the fake one in the hash table.  */
  static cpp_dir fake_source_dir;
  _cpp_find_file (pfile, fname, &fake_source_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;
      if (pfile->mi_cmacro
	  && pfile->mi_def_cmacro
	  && pfile->cb.get_suggestion)
	{
	  auto mi_cmacro = (const char *) NODE_NAME (pfile->mi_cmacro);
	  auto mi_def_cmacro = (const char *) NODE_NAME (pfile->mi_def_cmacro);
	  const char *names[] = { mi_def_cmacro, NULL };
	  if (pfile->cb.get_suggestion (pfile, mi_cmacro, names)
	      && cpp_warning_with_line (pfile, CPP_W_HEADER_GUARD,
					pfile->mi_loc, 0,
					"header guard %qs followed by "
					"%<#define%> of a different macro",
					mi_cmacro))
	    cpp_error_at (pfile, CPP_DL_NOTE, pfile->mi_def_loc,
			  "%qs is defined here; did you mean %qs?",
			  mi_def_cmacro, 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;
}

/* 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_file_path (_cpp_file *f)
{
  return f->path;
}

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

/* Return the directory where FILE was found.  */
struct cpp_dir *
_cpp_get_file_dir (_cpp_file *file)
{
  return file->dir;
}

/* 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.

   EMBED is include chain for #embed <>.  */
void
cpp_set_include_chains (cpp_reader *pfile, cpp_dir *quote, cpp_dir *bracket,
			cpp_dir *embed, int quote_ignores_source_dir)
{
  pfile->quote_include = quote;
  pfile->bracket_include = quote;
  pfile->quote_ignores_source_dir = quote_ignores_source_dir;
  pfile->embed_include = embed;

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

/* 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 || (p2 && 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 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,
					 /* suppress_diagnostic = */ true);
  if (!start_dir)
    return false;
  _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;
}
