]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gcc/cppfiles.c
Imported gcc-4.4.3
[msp430-gcc.git] / gcc / cppfiles.c
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
deleted file mode 100644 (file)
index cad35c2..0000000
+++ /dev/null
@@ -1,1200 +0,0 @@
-/* Part of CPP library.  (include file handling)
-   Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998,
-   1999, 2000, 2001, 2002 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
-
-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 2, 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; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#include "config.h"
-#include "system.h"
-#include "cpplib.h"
-#include "cpphash.h"
-#include "intl.h"
-#include "mkdeps.h"
-#include "splay-tree.h"
-
-#ifdef HAVE_MMAP_FILE
-# include <sys/mman.h>
-# ifndef MMAP_THRESHOLD
-#  define MMAP_THRESHOLD 3 /* Minimum page count to mmap the file.  */
-# endif
-# if MMAP_THRESHOLD
-#  define TEST_THRESHOLD(size, pagesize) \
-     (size / pagesize >= MMAP_THRESHOLD && (size % pagesize) != 0)
-   /* Use mmap if the file is big enough to be worth it (controlled
-      by MMAP_THRESHOLD) and if we can safely count on there being
-      at least one readable NUL byte after the end of the file's
-      contents.  This is true for all tested operating systems when
-      the file size is not an exact multiple of the page size.  */
-#  ifndef __CYGWIN__
-#   define SHOULD_MMAP(size, pagesize) TEST_THRESHOLD (size, pagesize)
-#  else
-#   define WIN32_LEAN_AND_MEAN
-#   include <windows.h>
-    /* Cygwin can't correctly emulate mmap under Windows 9x style systems so
-       disallow use of mmap on those systems.  Windows 9x does not zero fill
-       memory at EOF and beyond, as required.  */
-#   define SHOULD_MMAP(size, pagesize) ((GetVersion() & 0x80000000) \
-                                       ? 0 : TEST_THRESHOLD (size, pagesize))
-#  endif
-# endif
-
-#else  /* No MMAP_FILE */
-#  undef MMAP_THRESHOLD
-#  define MMAP_THRESHOLD 0
-#endif
-
-#ifndef O_BINARY
-# define O_BINARY 0
-#endif
-
-/* If errno is inspected immediately after a system call fails, it will be
-   nonzero, and no error number will ever be zero.  */
-#ifndef ENOENT
-# define ENOENT 0
-#endif
-#ifndef ENOTDIR
-# define ENOTDIR 0
-#endif
-
-/* Suppress warning about function macros used w/o arguments in traditional
-   C.  It is unlikely that glibc's strcmp macro helps this file at all.  */
-#undef strcmp
-
-/* This structure is used for the table of all includes.  */
-struct include_file
-{
-  const char *name;            /* actual path name of file */
-  const cpp_hashnode *cmacro;  /* macro, if any, preventing reinclusion.  */
-  const struct search_path *foundhere;
-                               /* location in search path where file was
-                                  found, for #include_next and sysp.  */
-  const unsigned char *buffer; /* pointer to cached file contents */
-  struct stat st;              /* copy of stat(2) data for file */
-  int fd;                      /* fd open on file (short term storage only) */
-  int err_no;                  /* errno obtained if opening a file failed */
-  unsigned short include_count;        /* number of times file has been read */
-  unsigned short refcnt;       /* number of stacked buffers using this file */
-  unsigned char mapped;                /* file buffer is mmapped */
-};
-
-/* 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_TOO_BIG(ST) ((ST).st_fab_rfm == FAB_C_VAR)
-#else
-# define STAT_SIZE_TOO_BIG(ST) 0
-#endif
-
-/* The cmacro works like this: If it's NULL, the file is to be
-   included again.  If it's NEVER_REREAD, the file is never to be
-   included again.  Otherwise it is a macro hashnode, and the file is
-   to be included again if the macro is defined.  */
-#define NEVER_REREAD ((const cpp_hashnode *)-1)
-#define DO_NOT_REREAD(inc) \
-((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \
-                  || (inc)->cmacro->type == NT_MACRO))
-#define NO_INCLUDE_PATH ((struct include_file *) -1)
-
-static struct file_name_map *read_name_map
-                               PARAMS ((cpp_reader *, const char *));
-static char *read_filename_string PARAMS ((int, FILE *));
-static char *remap_filename    PARAMS ((cpp_reader *, char *,
-                                        struct search_path *));
-static struct search_path *search_from PARAMS ((cpp_reader *,
-                                               enum include_type));
-static struct include_file *
-       find_include_file PARAMS ((cpp_reader *, const cpp_token *,
-                                  enum include_type));
-static struct include_file *open_file PARAMS ((cpp_reader *, const char *));
-static int read_include_file   PARAMS ((cpp_reader *, struct include_file *));
-static bool stack_include_file PARAMS ((cpp_reader *, struct include_file *));
-static void purge_cache        PARAMS ((struct include_file *));
-static void destroy_node       PARAMS ((splay_tree_value));
-static int report_missing_guard                PARAMS ((splay_tree_node, void *));
-static splay_tree_node find_or_create_entry PARAMS ((cpp_reader *,
-                                                    const char *));
-static void handle_missing_header PARAMS ((cpp_reader *, const char *, int));
-static int remove_component_p  PARAMS ((const char *));
-
-/* Set up the splay tree we use to store information about all the
-   file names seen in this compilation.  We also have entries for each
-   file we tried to open but failed; this saves system calls since we
-   don't try to open it again in future.
-
-   The key of each node is the file name, after processing by
-   _cpp_simplify_pathname.  The path name may or may not be absolute.
-   The path string has been malloced, as is automatically freed by
-   registering free () as the splay tree key deletion function.
-
-   A node's value is a pointer to a struct include_file, and is never
-   NULL.  */
-void
-_cpp_init_includes (pfile)
-     cpp_reader *pfile;
-{
-  pfile->all_include_files
-    = splay_tree_new ((splay_tree_compare_fn) strcmp,
-                     (splay_tree_delete_key_fn) free,
-                     destroy_node);
-}
-
-/* Tear down the splay tree.  */
-void
-_cpp_cleanup_includes (pfile)
-     cpp_reader *pfile;
-{
-  splay_tree_delete (pfile->all_include_files);
-}
-
-/* Free a node.  The path string is automatically freed.  */
-static void
-destroy_node (v)
-     splay_tree_value v;
-{
-  struct include_file *f = (struct include_file *)v;
-
-  if (f)
-    {
-      purge_cache (f);
-      free (f);
-    }
-}
-
-/* Mark a file to not be reread (e.g. #import, read failure).  */
-void
-_cpp_never_reread (file)
-     struct include_file *file;
-{
-  file->cmacro = NEVER_REREAD;
-}
-
-/* Lookup a filename, which is simplified after making a copy, and
-   create an entry if none exists.  errno is nonzero iff a (reported)
-   stat() error occurred during simplification.  */
-static splay_tree_node
-find_or_create_entry (pfile, fname)
-     cpp_reader *pfile;
-     const char *fname;
-{
-  splay_tree_node node;
-  struct include_file *file;
-  char *name = xstrdup (fname);
-
-  _cpp_simplify_pathname (name);
-  node = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
-  if (node)
-    free (name);
-  else
-    {
-      file = xcnew (struct include_file);
-      file->name = name;
-      file->err_no = errno;
-      node = splay_tree_insert (pfile->all_include_files,
-                               (splay_tree_key) file->name,
-                               (splay_tree_value) file);
-    }
-
-  return node;
-}
-
-/* Enter a file name in the splay tree, for the sake of cpp_included.  */
-void
-_cpp_fake_include (pfile, fname)
-     cpp_reader *pfile;
-     const char *fname;
-{
-  find_or_create_entry (pfile, fname);
-}
-
-/* Given a file name, look it up in the cache; if there is no entry,
-   create one with a non-NULL value (regardless of success in opening
-   the file).  If the file doesn't exist or is inaccessible, this
-   entry is flagged so we don't attempt to open it again in the
-   future.  If the file isn't open, open it.  The empty string is
-   interpreted as stdin.
-
-   Returns an include_file structure with an open file descriptor on
-   success, or NULL on failure.  */
-static struct include_file *
-open_file (pfile, filename)
-     cpp_reader *pfile;
-     const char *filename;
-{
-  splay_tree_node nd = find_or_create_entry (pfile, filename);
-  struct include_file *file = (struct include_file *) nd->value;
-
-  if (file->err_no)
-    {
-      /* Ugh.  handle_missing_header () needs errno to be set.  */
-      errno = file->err_no;
-      return 0;
-    }
-
-  /* Don't reopen an idempotent file.  */
-  if (DO_NOT_REREAD (file))
-    return file;
-      
-  /* Don't reopen one which is already loaded.  */
-  if (file->buffer != NULL)
-    return file;
-
-  /* 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.
-
-     Special case: the empty string is translated to stdin.  */
-
-  if (filename[0] == '\0')
-    file->fd = 0;
-  else
-    file->fd = open (file->name, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
-
-  if (file->fd != -1 && fstat (file->fd, &file->st) == 0)
-    {
-      if (!S_ISDIR (file->st.st_mode))
-       return file;
-
-      /* If it's a directory, we return null and continue the search
-        as the file we're looking for may appear elsewhere in the
-        search path.  */
-      errno = ENOENT;
-      close (file->fd);
-      file->fd = -1;
-    }
-
-  file->err_no = errno;
-  return 0;
-}
-
-/* Place the file referenced by INC into a new buffer on the buffer
-   stack, unless there are errors, or the file is not re-included
-   because of e.g. multiple-include guards.  Returns true if a buffer
-   is stacked.  */
-static bool
-stack_include_file (pfile, inc)
-     cpp_reader *pfile;
-     struct include_file *inc;
-{
-  cpp_buffer *fp;
-  int sysp;
-  const char *filename;
-
-  if (DO_NOT_REREAD (inc))
-    return false;
-
-  sysp = MAX ((pfile->map ? pfile->map->sysp : 0),
-             (inc->foundhere ? inc->foundhere->sysp : 0));
-
-  /* Add the file to the dependencies on its first inclusion.  */
-  if (CPP_OPTION (pfile, print_deps) > !!sysp && !inc->include_count)
-    {
-      if (pfile->buffer || CPP_OPTION (pfile, deps_ignore_main_file) == 0)
-       deps_add_dep (pfile->deps, inc->name);
-    }
-
-  /* Not in cache?  */
-  if (! inc->buffer)
-    {
-      if (read_include_file (pfile, inc))
-       {
-         /* If an error occurs, do not try to read this file again.  */
-         _cpp_never_reread (inc);
-         return false;
-       }
-      /* Mark a regular, zero-length file never-reread.  We read it,
-        NUL-terminate it, and stack it once, so preprocessing a main
-        file of zero length does not raise an error.  */
-      if (S_ISREG (inc->st.st_mode) && inc->st.st_size == 0)
-       _cpp_never_reread (inc);
-      close (inc->fd);
-      inc->fd = -1;
-    }
-
-  if (pfile->buffer)
-    /* We don't want MI guard advice for the main file.  */
-    inc->include_count++;
-
-  /* Push a buffer.  */
-  fp = cpp_push_buffer (pfile, inc->buffer, inc->st.st_size,
-                       /* from_stage3 */ CPP_OPTION (pfile, preprocessed), 0);
-  fp->inc = inc;
-  fp->inc->refcnt++;
-
-  /* Initialise controlling macro state.  */
-  pfile->mi_valid = true;
-  pfile->mi_cmacro = 0;
-
-  /* Generate the call back.  */
-  filename = inc->name;
-  if (*filename == '\0')
-    filename = "<stdin>";
-  _cpp_do_file_change (pfile, LC_ENTER, filename, 1, sysp);
-
-  return true;
-}
-
-/* Read the file referenced by INC into the file cache.
-
-   If fd points to a plain file, we might be able to mmap it; we can
-   definitely allocate the buffer all at once.  If fd is a pipe or
-   terminal, we can't do either.  If fd is something weird, like a
-   block device, we don't want to read it at all.
-
-   Unfortunately, different systems use different st.st_mode values
-   for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
-   zero the entire struct stat except a couple fields.  Hence we don't
-   even try to figure out what something is, except for plain files
-   and block devices.
-
-   FIXME: Flush file cache and try again if we run out of memory.  */
-static int
-read_include_file (pfile, inc)
-     cpp_reader *pfile;
-     struct include_file *inc;
-{
-  ssize_t size, offset, count;
-  U_CHAR *buf;
-#if MMAP_THRESHOLD
-  static int pagesize = -1;
-#endif
-
-  if (S_ISREG (inc->st.st_mode))
-    {
-      /* 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 (inc->st.st_size > INTTYPE_MAXIMUM (ssize_t))
-       {
-         cpp_error (pfile, "%s is too large", inc->name);
-         goto fail;
-       }
-      size = inc->st.st_size;
-
-      inc->mapped = 0;
-#if MMAP_THRESHOLD
-      if (pagesize == -1)
-       pagesize = getpagesize ();
-
-      if (SHOULD_MMAP (size, pagesize))
-       {
-         buf = (U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, inc->fd, 0);
-         if (buf == (U_CHAR *)-1)
-           goto perror_fail;
-         inc->mapped = 1;
-       }
-      else
-#endif
-       {
-         buf = (U_CHAR *) xmalloc (size + 1);
-         offset = 0;
-         while (offset < size)
-           {
-             count = read (inc->fd, buf + offset, size - offset);
-             if (count < 0)
-               goto perror_fail;
-             if (count == 0)
-               {
-                 if (!STAT_SIZE_TOO_BIG (inc->st))
-                   cpp_warning
-                     (pfile, "%s is shorter than expected", inc->name);
-                 size = offset;
-                 buf = xrealloc (buf, size + 1);
-                 inc->st.st_size = size;
-                 break;
-               }
-             offset += count;
-           }
-         /* The lexer requires that the buffer be NUL-terminated.  */
-         buf[size] = '\0';
-       }
-    }
-  else if (S_ISBLK (inc->st.st_mode))
-    {
-      cpp_error (pfile, "%s is a block device", inc->name);
-      goto fail;
-    }
-  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;
-
-      buf = (U_CHAR *) xmalloc (size + 1);
-      offset = 0;
-      while ((count = read (inc->fd, buf + offset, size - offset)) > 0)
-       {
-         offset += count;
-         if (offset == size)
-           {
-             size *= 2;
-             buf = xrealloc (buf, size + 1);
-           }
-       }
-      if (count < 0)
-       goto perror_fail;
-
-      if (offset + 1 < size)
-       buf = xrealloc (buf, offset + 1);
-
-      /* The lexer requires that the buffer be NUL-terminated.  */
-      buf[offset] = '\0';
-      inc->st.st_size = offset;
-    }
-
-  inc->buffer = buf;
-  return 0;
-
- perror_fail:
-  cpp_error_from_errno (pfile, inc->name);
- fail:
-  return 1;
-}
-
-/* Drop INC's buffer from memory, if we are unlikely to need it again.  */
-static void
-purge_cache (inc)
-     struct include_file *inc;
-{
-  if (inc->buffer)
-    {
-#if MMAP_THRESHOLD
-      if (inc->mapped)
-       munmap ((PTR) inc->buffer, inc->st.st_size);
-      else
-#endif
-       free ((PTR) inc->buffer);
-      inc->buffer = NULL;
-    }
-}
-
-/* Return 1 if the file named by FNAME has been included before in
-   any context, 0 otherwise.  */
-int
-cpp_included (pfile, fname)
-     cpp_reader *pfile;
-     const char *fname;
-{
-  struct search_path *path;
-  char *name, *n;
-  splay_tree_node nd;
-
-  if (IS_ABSOLUTE_PATHNAME (fname))
-    {
-      /* Just look it up.  */
-      nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) fname);
-      return (nd && nd->value);
-    }
-      
-  /* Search directory path for the file.  */
-  name = (char *) alloca (strlen (fname) + pfile->max_include_len + 2);
-  for (path = CPP_OPTION (pfile, quote_include); path; path = path->next)
-    {
-      memcpy (name, path->name, path->len);
-      name[path->len] = '/';
-      strcpy (&name[path->len + 1], fname);
-      if (CPP_OPTION (pfile, remap))
-       n = remap_filename (pfile, name, path);
-      else
-       n = name;
-
-      nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) n);
-      if (nd && nd->value)
-       return 1;
-    }
-  return 0;
-}
-
-/* Search for HEADER.  Return 0 if there is no such file (or it's
-   un-openable), in which case an error code will be in errno.  If
-   there is no include path to use it returns NO_INCLUDE_PATH,
-   otherwise an include_file structure.  If this request originates
-   from a directive of TYPE #include_next, set INCLUDE_NEXT to true.  */
-static struct include_file *
-find_include_file (pfile, header, type)
-     cpp_reader *pfile;
-     const cpp_token *header;
-     enum include_type type;
-{
-  const char *fname = (const char *) header->val.str.text;
-  struct search_path *path;
-  struct include_file *file;
-  char *name, *n;
-
-  if (IS_ABSOLUTE_PATHNAME (fname))
-    return open_file (pfile, fname);
-
-  /* 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 && pfile->buffer->inc->foundhere)
-    path = pfile->buffer->inc->foundhere->next;
-  else if (header->type == CPP_HEADER_NAME)
-    path = CPP_OPTION (pfile, bracket_include);
-  else
-    path = search_from (pfile, type);
-
-  if (path == NULL)
-    {
-      cpp_error (pfile, "no include path in which to find %s", fname);
-      return NO_INCLUDE_PATH;
-    }
-
-  /* Search directory path for the file.  */
-  name = (char *) alloca (strlen (fname) + pfile->max_include_len + 2);
-  for (; path; path = path->next)
-    {
-      int len = path->len;
-      memcpy (name, path->name, len);
-      /* Don't turn / into // or // into ///; // may be a namespace
-        escape.  */
-      if (name[len-1] == '/')
-       len--;
-      name[len] = '/';
-      strcpy (&name[len + 1], fname);
-      if (CPP_OPTION (pfile, remap))
-       n = remap_filename (pfile, name, path);
-      else
-       n = name;
-
-      file = open_file (pfile, n);
-      if (file)
-       {
-         file->foundhere = path;
-         return file;
-       }
-    }
-
-  return 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 (pfile, syshdr, externc)
-     cpp_reader *pfile;
-     int syshdr, externc;
-{
-  int flags = 0;
-
-  /* 1 = system header, 2 = system header to be treated as C.  */
-  if (syshdr)
-    flags = 1 + (externc != 0);
-  _cpp_do_file_change (pfile, LC_RENAME, pfile->map->to_file,
-                      SOURCE_LINE (pfile->map, pfile->line), flags);
-}
-
-/* Report on all files that might benefit from a multiple include guard.
-   Triggered by -H.  */
-void
-_cpp_report_missing_guards (pfile)
-     cpp_reader *pfile;
-{
-  int banner = 0;
-  splay_tree_foreach (pfile->all_include_files, report_missing_guard,
-                     (PTR) &banner);
-}
-
-/* Callback function for splay_tree_foreach().  */
-static int
-report_missing_guard (n, b)
-     splay_tree_node n;
-     void *b;
-{
-  struct include_file *f = (struct include_file *) n->value;
-  int *bannerp = (int *)b;
-
-  if (f && f->cmacro == 0 && f->include_count == 1)
-    {
-      if (*bannerp == 0)
-       {
-         fputs (_("Multiple include guards may be useful for:\n"), stderr);
-         *bannerp = 1;
-       }
-      fputs (f->name, stderr);
-      putc ('\n', stderr);
-    }
-  return 0;
-}
-
-/* Create a dependency for file FNAME, or issue an error message as
-   appropriate.  ANGLE_BRACKETS is non-zero if the file was bracketed
-   like <..>.  */
-static void
-handle_missing_header (pfile, fname, angle_brackets)
-     cpp_reader *pfile;
-     const char *fname;
-     int angle_brackets;
-{
-  int print_dep = CPP_PRINT_DEPS(pfile) > (angle_brackets || pfile->map->sysp);
-
-  if (CPP_OPTION (pfile, print_deps_missing_files) && print_dep)
-    {
-      if (!angle_brackets || IS_ABSOLUTE_PATHNAME (fname))
-       deps_add_dep (pfile->deps, fname);
-      else
-       {
-         /* If requested as a system header, assume it belongs in
-            the first system header directory.  */
-         struct search_path *ptr = CPP_OPTION (pfile, bracket_include);
-         char *p;
-         int len = 0, fname_len = strlen (fname);
-
-         if (ptr)
-           len = ptr->len;
-
-         p = (char *) alloca (len + fname_len + 2);
-         if (len)
-           {
-             memcpy (p, ptr->name, len);
-             p[len++] = '/';
-           }
-         memcpy (p + len, fname, fname_len + 1);
-         deps_add_dep (pfile->deps, p);
-       }
-    }
-  /* If -M was specified, then don't count this as an error, because
-     we can still produce correct output.  Otherwise, we can't produce
-     correct output, because there may be dependencies we need inside
-     the missing file, and we don't know what directory this missing
-     file exists in.  FIXME: Use a future cpp_diagnostic_with_errno ()
-     for both of these cases.  */
-  else if (CPP_PRINT_DEPS (pfile) && ! print_dep)
-    cpp_warning (pfile, "%s: %s", fname, xstrerror (errno));
-  else
-    cpp_error_from_errno (pfile, fname);
-}
-
-/* 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_execute_include (pfile, header, type)
-     cpp_reader *pfile;
-     const cpp_token *header;
-     enum include_type type;
-{
-  bool stacked = false;
-  struct include_file *inc = find_include_file (pfile, header, type);
-
-  if (inc == 0)
-    handle_missing_header (pfile, (const char *) header->val.str.text,
-                          header->type == CPP_HEADER_NAME);
-  else if (inc != NO_INCLUDE_PATH)
-    {
-      stacked = stack_include_file (pfile, inc);
-
-      if (type == IT_IMPORT)
-       _cpp_never_reread (inc);
-    }
-
-  return stacked;
-}
-
-/* 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
-   newer, return 1, otherwise 0.  */
-int
-_cpp_compare_file_date (pfile, header)
-     cpp_reader *pfile;
-     const cpp_token *header;
-{
-  struct include_file *inc = find_include_file (pfile, header, 0);
-  
-  if (inc == NULL || inc == NO_INCLUDE_PATH)
-    return -1;
-
-  if (inc->fd > 0)
-    {
-      close (inc->fd);
-      inc->fd = -1;
-    }
-    
-  return inc->st.st_mtime > pfile->buffer->inc->st.st_mtime;
-}
-
-
-/* Push an input buffer and load it up with the contents of FNAME.  If
-   FNAME is "", read standard input.  Return true if a buffer was
-   stacked.  */
-bool
-_cpp_read_file (pfile, fname)
-     cpp_reader *pfile;
-     const char *fname;
-{
-  struct include_file *f = open_file (pfile, fname);
-
-  if (f == NULL)
-    {
-      cpp_error_from_errno (pfile, fname);
-      return false;
-    }
-
-  return stack_include_file (pfile, f);
-}
-
-/* Do appropriate cleanup when a file INC's buffer is popped off the
-   input stack.  Push the next -include file, if any remain.  */
-bool
-_cpp_pop_file_buffer (pfile, inc)
-     cpp_reader *pfile;
-     struct include_file *inc;
-{
-  bool pushed = false;
-
-  /* Record the inclusion-preventing macro, which could be NULL
-     meaning no controlling macro.  */
-  if (pfile->mi_valid && inc->cmacro == NULL)
-    inc->cmacro = pfile->mi_cmacro;
-
-  /* Invalidate control macros in the #including file.  */
-  pfile->mi_valid = false;
-
-  inc->refcnt--;
-  if (inc->refcnt == 0 && DO_NOT_REREAD (inc))
-    purge_cache (inc);
-
-  /* Don't generate a callback for popping the main file.  */
-  if (pfile->buffer)
-    {
-      _cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0);
-
-      /* Finally, push the next -included file, if any.  */
-      if (!pfile->buffer->prev)
-       pushed = _cpp_push_next_buffer (pfile);
-    }
-
-  return pushed;
-}
-
-/* Returns the first place in the include chain to start searching for
-   "" includes.  This involves stripping away the basename of the
-   current file, unless -I- was specified.
-
-   If we're handling -include or -imacros, use the "" chain, but with
-   the preprocessor's cwd prepended.  */
-static struct search_path *
-search_from (pfile, type)
-     cpp_reader *pfile;
-     enum include_type type;
-{
-  cpp_buffer *buffer = pfile->buffer;
-  unsigned int dlen;
-
-  /* Command line uses the cwd, and does not cache the result.  */
-  if (type == IT_CMDLINE)
-    goto use_cwd;
-
-  /* Ignore the current file's directory if -I- was given.  */
-  if (CPP_OPTION (pfile, ignore_srcdir))
-    return CPP_OPTION (pfile, quote_include);
-
-  if (! buffer->search_cached)
-    {
-      buffer->search_cached = 1;
-
-      dlen = lbasename (buffer->inc->name) - buffer->inc->name;
-
-      if (dlen)
-       {
-         /* We don't guarantee NAME is null-terminated.  This saves
-            allocating and freeing memory.  Drop a trailing '/'.  */
-         buffer->dir.name = buffer->inc->name;
-         if (dlen > 1)
-           dlen--;
-       }
-      else
-       {
-       use_cwd:
-         buffer->dir.name = ".";
-         dlen = 1;
-       }
-
-      if (dlen > pfile->max_include_len)
-       pfile->max_include_len = dlen;
-
-      buffer->dir.len = dlen;
-      buffer->dir.next = CPP_OPTION (pfile, quote_include);
-      buffer->dir.sysp = pfile->map->sysp;
-    }
-
-  return &buffer->dir;
-}
-
-/* The file_name_map structure holds a mapping of file names for a
-   particular directory.  This mapping is read from the file named
-   FILE_NAME_MAP_FILE in that directory.  Such a file can be used to
-   map filenames on a file system with severe filename restrictions,
-   such as DOS.  The format of the file name map file is just a series
-   of lines with two tokens on each line.  The first token is the name
-   to map, and the second token is the actual name to use.  */
-struct file_name_map
-{
-  struct file_name_map *map_next;
-  char *map_from;
-  char *map_to;
-};
-
-#define FILE_NAME_MAP_FILE "header.gcc"
-
-/* Read a space delimited string of unlimited length from a stdio
-   file F.  */
-static char *
-read_filename_string (ch, f)
-     int ch;
-     FILE *f;
-{
-  char *alloc, *set;
-  int len;
-
-  len = 20;
-  set = alloc = xmalloc (len + 1);
-  if (! is_space(ch))
-    {
-      *set++ = ch;
-      while ((ch = getc (f)) != EOF && ! is_space(ch))
-       {
-         if (set - alloc == len)
-           {
-             len *= 2;
-             alloc = xrealloc (alloc, len + 1);
-             set = alloc + len / 2;
-           }
-         *set++ = ch;
-       }
-    }
-  *set = '\0';
-  ungetc (ch, f);
-  return alloc;
-}
-
-/* This structure holds a linked list of file name maps, one per directory.  */
-struct file_name_map_list
-{
-  struct file_name_map_list *map_list_next;
-  char *map_list_name;
-  struct file_name_map *map_list_map;
-};
-
-/* Read the file name map file for DIRNAME.  */
-static struct file_name_map *
-read_name_map (pfile, dirname)
-     cpp_reader *pfile;
-     const char *dirname;
-{
-  struct file_name_map_list *map_list_ptr;
-  char *name;
-  FILE *f;
-
-  /* Check the cache of directories, and mappings in their remap file.  */
-  for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
-       map_list_ptr = map_list_ptr->map_list_next)
-    if (! strcmp (map_list_ptr->map_list_name, dirname))
-      return map_list_ptr->map_list_map;
-
-  map_list_ptr = ((struct file_name_map_list *)
-                 xmalloc (sizeof (struct file_name_map_list)));
-  map_list_ptr->map_list_name = xstrdup (dirname);
-
-  /* The end of the list ends in NULL.  */
-  map_list_ptr->map_list_map = NULL;
-
-  name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
-  strcpy (name, dirname);
-  if (*dirname)
-    strcat (name, "/");
-  strcat (name, FILE_NAME_MAP_FILE);
-  f = fopen (name, "r");
-
-  /* Silently return NULL if we cannot open.  */
-  if (f)
-    {
-      int ch;
-      int dirlen = strlen (dirname);
-
-      while ((ch = getc (f)) != EOF)
-       {
-         char *from, *to;
-         struct file_name_map *ptr;
-
-         if (is_space(ch))
-           continue;
-         from = read_filename_string (ch, f);
-         while ((ch = getc (f)) != EOF && is_hspace(ch))
-           ;
-         to = read_filename_string (ch, f);
-
-         ptr = ((struct file_name_map *)
-                xmalloc (sizeof (struct file_name_map)));
-         ptr->map_from = from;
-
-         /* Make the real filename absolute.  */
-         if (IS_ABSOLUTE_PATHNAME (to))
-           ptr->map_to = to;
-         else
-           {
-             ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
-             strcpy (ptr->map_to, dirname);
-             ptr->map_to[dirlen] = '/';
-             strcpy (ptr->map_to + dirlen + 1, to);
-             free (to);
-           }         
-
-         ptr->map_next = map_list_ptr->map_list_map;
-         map_list_ptr->map_list_map = ptr;
-
-         while ((ch = getc (f)) != '\n')
-           if (ch == EOF)
-             break;
-       }
-      fclose (f);
-    }
-  
-  /* Add this information to the cache.  */
-  map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
-  CPP_OPTION (pfile, map_list) = map_list_ptr;
-
-  return map_list_ptr->map_list_map;
-}  
-
-/* Remap an unsimplified path NAME based on the file_name_map (if any)
-   for LOC.  */
-static char *
-remap_filename (pfile, name, loc)
-     cpp_reader *pfile;
-     char *name;
-     struct search_path *loc;
-{
-  struct file_name_map *map;
-  const char *from, *p;
-  char *dir;
-
-  if (! loc->name_map)
-    {
-      /* Get a null-terminated path.  */
-      char *dname = alloca (loc->len + 1);
-      memcpy (dname, loc->name, loc->len);
-      dname[loc->len] = '\0';
-
-      loc->name_map = read_name_map (pfile, dname);
-      if (! loc->name_map)
-       return name;
-    }
-  
-  /* This works since NAME has not been simplified yet.  */
-  from = name + loc->len + 1;
-  
-  for (map = loc->name_map; map; map = map->map_next)
-    if (!strcmp (map->map_from, from))
-      return map->map_to;
-
-  /* Try to find a mapping file for the particular directory we are
-     looking in.  Thus #include <sys/types.h> will look up sys/types.h
-     in /usr/include/header.gcc and look up types.h in
-     /usr/include/sys/header.gcc.  */
-  p = strrchr (name, '/');
-  if (!p)
-    return name;
-
-  /* We know p != name as absolute paths don't call remap_filename.  */
-  if (p == name)
-    cpp_ice (pfile, "absolute file name in remap_filename");
-
-  dir = (char *) alloca (p - name + 1);
-  memcpy (dir, name, p - name);
-  dir[p - name] = '\0';
-  from = p + 1;
-  
-  for (map = read_name_map (pfile, dir); map; map = map->map_next)
-    if (! strcmp (map->map_from, from))
-      return map->map_to;
-
-  return name;
-}
-
-/* Returns true if it is safe to remove the final component of path,
-   when it is followed by a ".." component.  We use lstat to avoid
-   symlinks if we have it.  If not, we can still catch errors with
-   stat ().  */
-static int
-remove_component_p (path)
-     const char *path;
-{
-  struct stat s;
-  int result;
-
-#ifdef HAVE_LSTAT
-  result = lstat (path, &s);
-#else
-  result = stat (path, &s);
-#endif
-
-  /* There's no guarantee that errno will be unchanged, even on
-     success.  Cygwin's lstat(), for example, will often set errno to
-     ENOSYS.  In case of success, reset errno to zero.  */
-  if (result == 0)
-    errno = 0;
-
-  return result == 0 && S_ISDIR (s.st_mode);
-}
-
-/* Simplify a path name in place, deleting redundant components.  This
-   reduces OS overhead and guarantees that equivalent paths compare
-   the same (modulo symlinks).
-
-   Transforms made:
-   foo/bar/../quux     foo/quux
-   foo/./bar           foo/bar
-   foo//bar            foo/bar
-   /../quux            /quux
-   //quux              //quux  (POSIX allows leading // as a namespace escape)
-
-   Guarantees no trailing slashes.  All transforms reduce the length
-   of the string.  Returns PATH.  errno is 0 if no error occurred;
-   nonzero if an error occurred when using stat () or lstat ().  */
-char *
-_cpp_simplify_pathname (path)
-    char *path;
-{
-#ifndef VMS
-  char *from, *to;
-  char *base, *orig_base;
-  int absolute = 0;
-
-  errno = 0;
-  /* Don't overflow the empty path by putting a '.' in it below.  */
-  if (*path == '\0')
-    return path;
-
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  /* Convert all backslashes to slashes.  */
-  for (from = path; *from; from++)
-    if (*from == '\\') *from = '/';
-    
-  /* Skip over leading drive letter if present.  */
-  if (ISALPHA (path[0]) && path[1] == ':')
-    from = to = &path[2];
-  else
-    from = to = path;
-#else
-  from = to = path;
-#endif
-    
-  /* Remove redundant leading /s.  */
-  if (*from == '/')
-    {
-      absolute = 1;
-      to++;
-      from++;
-      if (*from == '/')
-       {
-         if (*++from == '/')
-           /* 3 or more initial /s are equivalent to 1 /.  */
-           while (*++from == '/');
-         else
-           /* On some hosts // differs from /; Posix allows this.  */
-           to++;
-       }
-    }
-
-  base = orig_base = to;
-  for (;;)
-    {
-      int move_base = 0;
-
-      while (*from == '/')
-       from++;
-
-      if (*from == '\0')
-       break;
-
-      if (*from == '.')
-       {
-         if (from[1] == '\0')
-           break;
-         if (from[1] == '/')
-           {
-             from += 2;
-             continue;
-           }
-         else if (from[1] == '.' && (from[2] == '/' || from[2] == '\0'))
-           {
-             /* Don't simplify if there was no previous component.  */
-             if (absolute && orig_base == to)
-               {
-                 from += 2;
-                 continue;
-               }
-             /* Don't simplify if the previous component was "../",
-                or if an error has already occurred with (l)stat.  */
-             if (base != to && errno == 0)
-               {
-                 /* We don't back up if it's a symlink.  */
-                 *to = '\0';
-                 if (remove_component_p (path))
-                   {
-                     while (to > base && *to != '/')
-                       to--;
-                     from += 2;
-                     continue;
-                   }
-               }
-             move_base = 1;
-           }
-       }
-
-      /* Add the component separator.  */
-      if (to > orig_base)
-       *to++ = '/';
-
-      /* Copy this component until the trailing null or '/'.  */
-      while (*from != '\0' && *from != '/')
-       *to++ = *from++;
-
-      if (move_base)
-       base = to;
-    }
-    
-  /* Change the empty string to "." so that it is not treated as stdin.
-     Null terminate.  */
-  if (to == path)
-    *to++ = '.';
-  *to = '\0';
-
-  return path;
-#else /* VMS  */
-  errno = 0;
-  return path;
-#endif /* !VMS  */
-}