* Makefile.in (C_AND_OBJC_OBJS, c-incpath.o, c-lex.o, LIBCPP_OBJS,
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 Mar 2003 14:31:21 +0000 (14:31 +0000)
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 Mar 2003 14:31:21 +0000 (14:31 +0000)
cppinit.o, cppdefault.o, fix-header): Update.
* c-incpath.c: New file.
* c-incpath.h: New file.
* c-lex.c: Include c-incpath.h.
(init_c_lex): Register path simplifier.
* c-opts.c: Include cppdefault.h and c-incpath.h.
(TARGET_SYSTEM_ROOT, verbose, iprefix, sysroot, std_inc,
std_cxx_inc, quote_chain_split, add_prefixed_path): New.
(COMMAND_LINE_OPTIONS): Add more options from cpplib.
(missing_arg, c_common_decode_option): Handle them.
(c_common_post_options): Register include chains.
(print_help): Update.
* cppdefault.h (struct default include): Update.
Move some macros to ...
* cppdefault.c: ... here.
(cpp_include_defaults): Add extra field add_sysroot.
* cppfiles.c (include_file, search_from, find_or_create_entry,
cpp_included, find_include_file, remap_filename): Update for
renaming of search_path to cpp_path, and of the chain headers.
(remove_component_p, _cpp_simplify_pathname): Move to c-incpath.c.
* cpphash.h (struct search_path): Move to cpplib.h.
(struct cpp_buffer, struct cpp_reader): Update.
(_cpp_simplify_pathname): Remove.
* cppinit.c: Don't include prefix.h and cppdefault.h.
(INO_T_EQ, INO_T_COPY, path_include, append_include_chain,
remove_dup_dir, remove_dup_nonsys_dirs, remove_dup_dirs,
init_standard_includes, BRACKET, SYSTEM, AFTER, no_dir,
no_pth, cpp_handle_options): Remove.
(struct pending_option): Remove chain members.
(cpp_destroy, cpp_read_main_file, COMMAND_LINE_OPTIONS,
cpp_handle_option): Update.
* cpplib.h (struct cpp_path, cpp_set_include_chains): New.
(struct cpp_options): Remove quote_include, bracket_include,
include_prefix, include_prefix_len, verbose, ignore_srcdir,
no_standard_includes, no_standard_cplusplus_includes.
(struct cpp_callbacks): Add simplify_path.
(cpp_handle_options): Remove.
* fix-header.c: Include c-incpath.h.
(read_scan_file): Update to use c-incpath functionality.
* doc/passes.texi: Update.
cp:
* Make-lang.in (CXX_C_OBJS): Update.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@63612 138bc75d-0d04-0410-961f-82ee72b054a4

16 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/c-incpath.c [new file with mode: 0644]
gcc/c-incpath.h [new file with mode: 0644]
gcc/c-lex.c
gcc/c-opts.c
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cppdefault.c
gcc/cppdefault.h
gcc/cppfiles.c
gcc/cpphash.h
gcc/cppinit.c
gcc/cpplib.h
gcc/doc/passes.texi
gcc/fix-header.c

index 90086bd..ed7f0ef 100644 (file)
@@ -1,3 +1,47 @@
+2003-03-01  Neil Booth  <neil@daikokuya.co.uk>
+
+       * Makefile.in (C_AND_OBJC_OBJS, c-incpath.o, c-lex.o, LIBCPP_OBJS,
+       cppinit.o, cppdefault.o, fix-header): Update.
+       * c-incpath.c: New file.
+       * c-incpath.h: New file.
+       * c-lex.c: Include c-incpath.h.
+       (init_c_lex): Register path simplifier.
+       * c-opts.c: Include cppdefault.h and c-incpath.h.
+       (TARGET_SYSTEM_ROOT, verbose, iprefix, sysroot, std_inc,
+       std_cxx_inc, quote_chain_split, add_prefixed_path): New.
+       (COMMAND_LINE_OPTIONS): Add more options from cpplib.
+       (missing_arg, c_common_decode_option): Handle them.
+       (c_common_post_options): Register include chains.
+       (print_help): Update.
+       * cppdefault.h (struct default include): Update.
+       Move some macros to ...
+       * cppdefault.c: ... here.
+       (cpp_include_defaults): Add extra field add_sysroot.
+       * cppfiles.c (include_file, search_from, find_or_create_entry,
+       cpp_included, find_include_file, remap_filename): Update for
+       renaming of search_path to cpp_path, and of the chain headers.
+       (remove_component_p, _cpp_simplify_pathname): Move to c-incpath.c.
+       * cpphash.h (struct search_path): Move to cpplib.h.
+       (struct cpp_buffer, struct cpp_reader): Update.
+       (_cpp_simplify_pathname): Remove.
+       * cppinit.c: Don't include prefix.h and cppdefault.h.
+       (INO_T_EQ, INO_T_COPY, path_include, append_include_chain,
+       remove_dup_dir, remove_dup_nonsys_dirs, remove_dup_dirs,
+       init_standard_includes, BRACKET, SYSTEM, AFTER, no_dir,
+       no_pth, cpp_handle_options): Remove.
+       (struct pending_option): Remove chain members.
+       (cpp_destroy, cpp_read_main_file, COMMAND_LINE_OPTIONS,
+       cpp_handle_option): Update.
+       * cpplib.h (struct cpp_path, cpp_set_include_chains): New.
+       (struct cpp_options): Remove quote_include, bracket_include,
+       include_prefix, include_prefix_len, verbose, ignore_srcdir,
+       no_standard_includes, no_standard_cplusplus_includes.
+       (struct cpp_callbacks): Add simplify_path.
+       (cpp_handle_options): Remove.
+       * fix-header.c: Include c-incpath.h.
+       (read_scan_file): Update to use c-incpath functionality.
+       * doc/passes.texi: Update.
+
 2003-03-01  Kazu Hirata  <kazu@cs.umass.edu>
 
        * config/h8300/h8300.c (bit_operand): Accept MEM only if it
index 9510321..22c1fe5 100644 (file)
@@ -759,6 +759,7 @@ CXX_TARGET_OBJS=@cxx_target_objs@
 # Language-specific object files for C and Objective C.
 C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
   c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
+  c-incpath.o cppdefault.o \
   c-objc-common.o c-dump.o c-pch.o libcpp.a $(C_TARGET_OBJS)
 
 # Language-specific object files for C.
@@ -1218,6 +1219,9 @@ $(parsedir)/c-parse.y: c-parse.in
          $(srcdir)/c-parse.in >>tmp-c-parse.y
        $(SHELL) $(srcdir)/move-if-change tmp-c-parse.y $(parsedir)/c-parse.y
 
+c-incpath.o: c-incpath.c c-incpath.h $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) \
+               intl.h prefix.h coretypes.h $(TM_H) cppdefault.h
+
 c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
     $(C_TREE_H) $(GGC_H) $(TARGET_H) flags.h function.h output.h $(EXPR_H) \
     debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H) c-pragma.h \
@@ -1226,8 +1230,8 @@ c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(
     $(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H)
 c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_TREE_H) \
     $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) c-common.h gtype-c.h
-c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
-    debug.h $(C_TREE_H) c-common.h real.h \
+c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+    $(RTL_H) debug.h $(C_TREE_H) c-common.h real.h c-incpath.h cppdefault.h \
     c-pragma.h input.h intl.h flags.h toplev.h output.h \
     mbchar.h $(CPPLIB_H) $(EXPR_H) $(TM_P_H)
 c-objc-common.o : c-objc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
@@ -2271,7 +2275,7 @@ PREPROCESSOR_DEFINES = \
   @TARGET_SYSTEM_ROOT_DEFINE@
 
 LIBCPP_OBJS =  cpplib.o cpplex.o cppmacro.o cppexp.o cppfiles.o cpptrad.o \
-               cpphash.o cpperror.o cppinit.o cppdefault.o cppmain.o \
+               cpphash.o cpperror.o cppinit.o cppmain.o \
                hashtable.o line-map.o mkdeps.o prefix.o mbchar.o cpppch.o
 
 LIBCPP_DEPS =  $(CPPLIB_H) cpphash.h line-map.h hashtable.h intl.h \
@@ -2294,11 +2298,11 @@ cpplib.o:   cpplib.c   $(LIBCPP_DEPS)
 cpphash.o:  cpphash.c  $(LIBCPP_DEPS)
 cpptrad.o:  cpptrad.c  $(LIBCPP_DEPS)
 cppfiles.o: cppfiles.c $(LIBCPP_DEPS) $(SPLAY_TREE_H) mkdeps.h
-cppinit.o:  cppinit.c  $(LIBCPP_DEPS) cppdefault.h mkdeps.h prefix.h
+cppinit.o:  cppinit.c  $(LIBCPP_DEPS) mkdeps.h prefix.h
 cpppch.o:   cpppch.c   $(LIBCPP_DEPS) mkdeps.h
 
-cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) cppdefault.h \
-       Makefile
+cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+       cppdefault.h Makefile
        $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
          $(PREPROCESSOR_DEFINES) \
          -c $(srcdir)/cppdefault.c $(OUTPUT_OPTION)
@@ -2512,9 +2516,9 @@ xsys-protos.h: $(GCC_PASSES) $(srcdir)/sys-protos.h deduced.h gen-protos$(build_
 # This is nominally a 'build' program, but it's run only when host==build,
 # so we can (indeed, must) use $(LIBDEPS) and $(LIBS).
 fix-header$(build_exeext): fix-header.o scan-decls.o scan.o xsys-protos.h \
-           $(LIBDEPS) libcpp.a
+           c-incpath.o cppdefault.o $(LIBDEPS) libcpp.a
        $(BUILD_CC) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ fix-header.o \
-          scan-decls.o scan.o libcpp.a $(LIBS)
+          c-incpath.o cppdefault.o scan-decls.o scan.o libcpp.a $(LIBS)
 
 fix-header.o: fix-header.c $(OBSTACK_H) scan.h \
        xsys-protos.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(CPPLIB_H)
diff --git a/gcc/c-incpath.c b/gcc/c-incpath.c
new file mode 100644 (file)
index 0000000..96bf69d
--- /dev/null
@@ -0,0 +1,510 @@
+/* Set up combined include path chain for the preprocessor.
+   Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   Broken out of cppinit.c and cppfiles.c and rewritten Mar 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 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 "coretypes.h"
+#include "tm.h"
+#include "cpplib.h"
+#include "prefix.h"
+#include "intl.h"
+#include "c-incpath.h"
+#include "cppdefault.h"
+
+/* Windows does not natively support inodes, and neither does MSDOS.
+   Cygwin's emulation can generate non-unique inodes, so don't use it.
+   VMS has non-numeric inodes.  */
+#ifdef VMS
+# define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
+# define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
+#else
+# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
+#  define INO_T_EQ(A, B) 0
+# else
+#  define INO_T_EQ(A, B) ((A) == (B))
+# endif
+# define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
+#endif
+
+static void add_env_var_paths PARAMS ((const char *, int));
+static void add_standard_paths PARAMS ((const char *, const char *, int));
+static void free_path PARAMS ((struct cpp_path *, int));
+static void merge_include_chains PARAMS ((cpp_reader *, int));
+static int remove_component_p PARAMS ((const char *));
+static struct cpp_path *
+  remove_duplicates PARAMS ((cpp_reader *, struct cpp_path *,
+                            struct cpp_path *, struct cpp_path *, int));
+
+/* Include chains heads and tails.  */
+static struct cpp_path *heads[4];
+static struct cpp_path *tails[4];
+static bool quote_ignores_source_dir;
+enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS };
+
+/* Free an element of the include chain, possibly giving a reason.  */
+static void
+free_path (path, reason)
+     struct cpp_path *path;
+     int reason;
+{
+  switch (reason)
+    {
+    case REASON_DUP:
+    case REASON_DUP_SYS:
+      fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), path->name);
+      if (reason == REASON_DUP_SYS)
+       fprintf (stderr,
+ _("  as it is a non-system directory that duplicates a system directory\n"));
+      break;
+
+    case REASON_NOENT:
+      fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"),
+              path->name);
+      break;
+
+    case REASON_QUIET:
+    default:
+      break;
+    }
+
+  free ((PTR) path->name);
+  free (path);
+}
+
+/* Read ENV_VAR for a PATH_SEPARATOR-separated list of file names; and
+   append all the names to the search path CHAIN.  */
+static void
+add_env_var_paths (env_var, chain)
+     const char *env_var;
+     int chain;
+{
+  char *p, *q, *path;
+
+  GET_ENVIRONMENT (q, env_var);
+
+  if (!q)
+    return;
+
+  for (p = q; *q; p = q + 1)
+    {
+      q = p;
+      while (*q != 0 && *q != PATH_SEPARATOR)
+       q++;
+
+      if (p == q)
+       path = xstrdup (".");
+      else
+       {
+         path = xmalloc (q - p + 1);
+         memcpy (path, p, q - p);
+         path[q - p] = '\0';
+       }
+
+      add_path (path, chain, chain == SYSTEM);
+    }
+}
+
+/* Append the standard include chain defined in cppdefault.c.  */
+static void
+add_standard_paths (sysroot, iprefix, cxx_stdinc)
+     const char *sysroot, *iprefix;
+     int cxx_stdinc;
+{
+  const struct default_include *p;
+  size_t len = 0;
+
+  if (iprefix)
+    len = cpp_GCC_INCLUDE_DIR_len;
+
+  for (p = cpp_include_defaults; p->fname; p++)
+    {
+      if (!p->cplusplus || cxx_stdinc)
+       {
+         char *str;
+
+         /* Should this directory start with the sysroot?  */
+         if (sysroot && p->add_sysroot)
+           str = concat (sysroot, p->fname, NULL);
+         /* Does this directory start with the prefix?  If so, search
+            "translated" versions of GNU directories.  These have
+            /usr/local/lib/gcc... replaced by iprefix.  */
+         else if (len && !strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
+           str = concat (iprefix, p->fname + len, NULL);
+         else
+           str = update_path (p->fname, p->component);
+
+         add_path (str, SYSTEM, p->cxx_aware);
+       }
+    }
+}
+
+/* For each duplicate path in chain HEAD, keep just the first one.
+   Remove each path in chain HEAD that also exists in chain SYSTEM.
+   Set the NEXT pointer of the last path in the resulting chain to
+   JOIN, unless it duplicates JOIN in which case the last path is
+   removed.  Return the head of the resulting chain.  Any of HEAD,
+   JOIN and SYSTEM can be NULL.  */
+static struct cpp_path *
+remove_duplicates (pfile, head, system, join, verbose)
+     cpp_reader *pfile;
+     struct cpp_path *head;
+     struct cpp_path *system;
+     struct cpp_path *join;
+     int verbose;
+{
+  struct cpp_path **pcur, *tmp, *cur;
+  struct stat st;
+
+  for (pcur = &head; *pcur; )
+    {
+      int reason = REASON_QUIET;
+
+      cur = *pcur;
+      simplify_path (cur->name);
+
+      if (stat (cur->name, &st))
+       {
+         /* Dirs that don't exist are silently ignored, unless verbose.  */
+         if (errno != ENOENT)
+           cpp_errno (pfile, DL_ERROR, cur->name);
+         else
+           reason = REASON_NOENT;
+       }
+      else if (!S_ISDIR (st.st_mode))
+       cpp_error_with_line (pfile, DL_ERROR, 0, 0,
+                            "%s: not a directory", cur->name);
+      else
+       {
+         INO_T_COPY (cur->ino, st.st_ino);
+         cur->dev  = st.st_dev;
+
+         /* Remove this one if it is in the system chain.  */
+         reason = REASON_DUP_SYS;
+         for (tmp = system; tmp; tmp = tmp->next)
+           if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev)
+             break;
+
+         if (!tmp)
+           {
+             /* Dupicate of something earlier in the same chain?  */
+             reason = REASON_DUP;
+             for (tmp = head; tmp != cur; tmp = tmp->next)
+               if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev)
+                 break;
+
+             if (tmp == cur
+                 /* Last in the chain and duplicate of JOIN?  */
+                 && !(cur->next == NULL && join
+                      && INO_T_EQ (cur->ino, join->ino)
+                      && cur->dev == join->dev))
+               {
+                 /* Unique, so keep this directory.  */
+                 pcur = &cur->next;
+                 continue;
+               }
+           }
+       }
+
+      /* Remove this entry from the chain.  */
+      *pcur = cur->next;
+      free_path (cur, verbose ? reason: REASON_QUIET);
+    }
+
+  *pcur = join;
+  return head;
+}
+
+/* Merge the four include chains together in the order quote, bracket,
+   system, after.  Remove duplicate dirs (as determined by
+   INO_T_EQ()).
+
+   We can't just merge the lists and then uniquify them because then
+   we may lose directories from the <> search path that should be
+   there; consider -Ifoo -Ibar -I- -Ifoo -Iquux.  It is however safe
+   to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written -Ibar -I- -Ifoo
+   -Iquux.  */
+static void
+merge_include_chains (pfile, verbose)
+     cpp_reader *pfile;
+     int verbose;
+{
+  /* Join the SYSTEM and AFTER chains.  Remove duplicates in the
+     resulting SYSTEM chain.  */
+  if (heads[SYSTEM])
+    tails[SYSTEM]->next = heads[AFTER];
+  else
+    heads[SYSTEM] = heads[AFTER];
+  heads[SYSTEM] = remove_duplicates (pfile, heads[SYSTEM], 0, 0, verbose);
+
+  /* Remove duplicates from BRACKET that are in itself or SYSTEM, and
+     join it to SYSTEM.  */
+  heads[BRACKET] = remove_duplicates (pfile, heads[BRACKET], heads[SYSTEM],
+                                     heads[SYSTEM], verbose);
+
+  /* Remove duplicates from QUOTE that are in itself or SYSTEM, and
+     join it to BRACKET.  */
+  heads[QUOTE] = remove_duplicates (pfile, heads[QUOTE], heads[SYSTEM],
+                                   heads[BRACKET], verbose);
+
+  /* If verbose, print the list of dirs to search.  */
+  if (verbose)
+    {
+      struct cpp_path *p;
+
+      fprintf (stderr, _("#include \"...\" search starts here:\n"));
+      for (p = heads[QUOTE];; p = p->next)
+       {
+         if (p == heads[BRACKET])
+           fprintf (stderr, _("#include <...> search starts here:\n"));
+         if (!p)
+           break;
+         fprintf (stderr, " %s\n", p->name);
+       }
+      fprintf (stderr, _("End of search list.\n"));
+    }
+}
+
+/* Use given -I paths for #include "..." but not #include <...>, and
+   don't search the directory of the present file for #include "...".
+   (Note that -I. -I- is not the same as the default setup; -I. uses
+   the compiler's working dir.)  */
+void
+split_quote_chain ()
+{
+  heads[QUOTE] = heads[BRACKET];
+  tails[QUOTE] = tails[BRACKET];
+  heads[BRACKET] = NULL;
+  tails[BRACKET] = NULL;
+  /* This is NOT redundant.  */
+  quote_ignores_source_dir = true;
+}
+
+/* Add PATH to the include chain CHAIN. PATH must be malloc-ed and
+   NUL-terminated.  */
+void
+add_path (path, chain, cxx_aware)
+     char *path;
+     int chain;
+     int cxx_aware;
+{
+  struct cpp_path *p;
+
+  p = (struct cpp_path *) xmalloc (sizeof (struct cpp_path));
+  p->next = NULL;
+  p->name = path;
+  if (chain == SYSTEM || chain == AFTER)
+    p->sysp = 1 + (cxx_aware != 0);
+  else
+    p->sysp = 0;
+
+  if (tails[chain])
+    tails[chain]->next = p;
+  else
+    heads[chain] = p;
+  tails[chain] = p;
+}
+
+/* Exported function to handle include chain merging, duplicate
+   removal, and registration with cpplib.  */
+void
+register_include_chains (pfile, sysroot, iprefix,
+                        stdinc, cxx_stdinc, verbose)
+     cpp_reader *pfile;
+     const char *sysroot, *iprefix;
+     int stdinc, cxx_stdinc, verbose;
+{
+  static const char *const lang_env_vars[] =
+    { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
+      "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
+  cpp_options *cpp_opts = cpp_get_options (pfile);
+  size_t idx = (cpp_opts->objc ? 2: 0);
+
+  if (cpp_opts->cplusplus)
+    idx++;
+  else
+    cxx_stdinc = false;
+
+  /* CPATH and language-dependent environment variables may add to the
+     include chain.  */
+  add_env_var_paths ("CPATH", BRACKET);
+  add_env_var_paths (lang_env_vars[idx], SYSTEM);
+
+  /* Finally chain on the standard directories.  */
+  if (stdinc)
+    add_standard_paths (sysroot, iprefix, cxx_stdinc);
+
+  merge_include_chains (pfile, verbose);
+
+  cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET],
+                         quote_ignores_source_dir);
+}
+
+/* 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 ().  */
+void
+simplify_path (path)
+     char *path ATTRIBUTE_UNUSED;
+{
+#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;
+
+#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';
+#else  /* VMS */
+  errno = 0;
+#endif /* !VMS  */
+}
diff --git a/gcc/c-incpath.h b/gcc/c-incpath.h
new file mode 100644 (file)
index 0000000..860ea3c
--- /dev/null
@@ -0,0 +1,24 @@
+/* Set up combined include path for the preprocessor.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+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.  */
+
+extern void split_quote_chain  PARAMS ((void));
+extern void add_path           PARAMS ((char *, int, int));
+extern void register_include_chains PARAMS ((cpp_reader *, const char *,
+                                            const char *, int, int, int));
+extern void simplify_path      PARAMS ((char *));
+
+enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
index ab06820..e0617bd 100644 (file)
@@ -1,6 +1,6 @@
 /* Mainly the interface between cpplib and the C front ends.
    Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997
-   1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -41,6 +41,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tm_p.h"
 #include "splay-tree.h"
 #include "debug.h"
+#include "c-incpath.h"
 
 #ifdef MULTIBYTE_CHARS
 #include "mbchar.h"
@@ -124,6 +125,7 @@ init_c_lex (filename)
   cb->ident = cb_ident;
   cb->file_change = cb_file_change;
   cb->def_pragma = cb_def_pragma;
+  cb->simplify_path = simplify_path;
   cb->valid_pch = c_common_valid_pch;
   cb->read_pch = c_common_read_pch;
 
index 075112e..c5f25c9 100644 (file)
@@ -1,5 +1,5 @@
 /* C/ObjC/C++ command line option handling.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
    Contributed by Neil Booth.
 
 This file is part of GCC.
@@ -32,6 +32,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tree-inline.h"
 #include "diagnostic.h"
 #include "intl.h"
+#include "cppdefault.h"
+#include "c-incpath.h"
+
+#ifndef TARGET_SYSTEM_ROOT
+# define TARGET_SYSTEM_ROOT NULL
+#endif
 
 /* CPP's options.  */
 static cpp_options *cpp_opts;
@@ -49,9 +55,27 @@ static bool deps_append;
 /* If dependency switches (-MF etc.) have been given.  */
 static bool deps_seen;
 
+/* If -v seen.  */
+static bool verbose;
+
 /* Dependency output file.  */
 static const char *deps_file;
 
+/* The prefix given by -iprefix, if any.  */
+static const char *iprefix;
+
+/* The system root, if any.  Overridden by -isysroot.  */
+static const char *sysroot = TARGET_SYSTEM_ROOT;
+
+/* Zero disables all standard directories for headers.  */
+static bool std_inc = true;
+
+/* Zero disables the C++-specific standard directories for headers.  */
+static bool std_cxx_inc = true;
+
+/* If the quote chain has been split by -I-.  */
+static bool quote_chain_split;
+
 /* Number of deferred options, deferred options array size.  */
 static size_t deferred_count, deferred_size;
 
@@ -69,6 +93,7 @@ static void check_deps_environment_vars PARAMS ((void));
 static void preprocess_file PARAMS ((void));
 static void handle_deferred_opts PARAMS ((void));
 static void sanitize_cpp_opts PARAMS ((void));
+static void add_prefixed_path PARAMS ((const char *, size_t));
 
 #ifndef STDC_0_IN_SYSTEM_HEADERS
 #define STDC_0_IN_SYSTEM_HEADERS 0
@@ -117,6 +142,7 @@ static void sanitize_cpp_opts PARAMS ((void));
   OPT("CC",                     CL_ALL,   OPT_CC)                           \
   OPT("E",                     CL_ALL,   OPT_E)                             \
   OPT("H",                      CL_ALL,   OPT_H)                            \
+  OPT("I",                      CL_ALL | CL_ARG, OPT_I)                             \
   OPT("M",                      CL_ALL,   OPT_M)                            \
   OPT("MD",                     CL_ALL | CL_SEPARATE, OPT_MD)               \
   OPT("MF",                     CL_ALL | CL_ARG, OPT_MF)                    \
@@ -260,6 +286,12 @@ static void sanitize_cpp_opts PARAMS ((void));
   OPT("fweak",                 CL_CXX,   OPT_fweak)                         \
   OPT("fxref",                 CL_CXX,   OPT_fxref)                         \
   OPT("gen-decls",             CL_OBJC,  OPT_gen_decls)                     \
+  OPT("idirafter",              CL_ALL | CL_ARG, OPT_idirafter)              \
+  OPT("iprefix",               CL_ALL | CL_ARG, OPT_iprefix)                \
+  OPT("isysroot",               CL_ALL | CL_ARG, OPT_isysroot)               \
+  OPT("isystem",                CL_ALL | CL_ARG, OPT_isystem)                \
+  OPT("iwithprefix",            CL_ALL | CL_ARG, OPT_iwithprefix)            \
+  OPT("iwithprefixbefore",      CL_ALL | CL_ARG, OPT_iwithprefixbefore)             \
   OPT("lang-asm",              CL_C_ONLY, OPT_lang_asm)                     \
   OPT("lang-objc",              CL_ALL,   OPT_lang_objc)                    \
   OPT("nostdinc",               CL_ALL,   OPT_nostdinc)                             \
@@ -357,6 +389,9 @@ missing_arg (opt_index)
     case OPT_fname_mangling:
     case OPT_ftabstop:
     case OPT_ftemplate_depth:
+    case OPT_iprefix:
+    case OPT_iwithprefix:
+    case OPT_iwithprefixbefore:
     default:
       error ("missing argument to \"-%s\"", opt_text);
       break;
@@ -365,6 +400,13 @@ missing_arg (opt_index)
       error ("no class name specified with \"-%s\"", opt_text);
       break;
 
+    case OPT_I:
+    case OPT_idirafter:
+    case OPT_isysroot:
+    case OPT_isystem:
+      error ("missing path after \"-%s\"", opt_text);
+      break;
+
     case OPT_MF:
     case OPT_MD:
     case OPT_MMD:
@@ -654,6 +696,18 @@ c_common_decode_option (argc, argv)
       cpp_opts->print_include_names = 1;
       break;
 
+    case OPT_I:
+      if (strcmp (arg, "-"))
+       add_path (xstrdup (arg), BRACKET, 0);
+      else
+       {
+         if (quote_chain_split)
+           error ("-I- specified twice");
+         quote_chain_split = true;
+         split_quote_chain ();
+       }
+      break;
+
     case OPT_M:
     case OPT_MM:
       /* When doing dependencies with -M or -MM, suppress normal
@@ -1264,6 +1318,30 @@ c_common_decode_option (argc, argv)
       flag_gen_declaration = 1;
       break;
 
+    case OPT_idirafter:
+      add_path (xstrdup (arg), AFTER, 0);
+      break;
+
+    case OPT_iprefix:
+      iprefix = arg;
+      break;
+
+    case OPT_isysroot:
+      sysroot = arg;
+      break;
+
+    case OPT_isystem:
+      add_path (xstrdup (arg), SYSTEM, 0);
+      break;
+
+    case OPT_iwithprefix:
+      add_prefixed_path (arg, SYSTEM);
+      break;
+
+    case OPT_iwithprefixbefore:
+      add_prefixed_path (arg, BRACKET);
+      break;
+
     case OPT_lang_asm:
       cpp_set_lang (parse_in, CLK_ASM);
       break;
@@ -1273,14 +1351,11 @@ c_common_decode_option (argc, argv)
       break;
 
     case OPT_nostdinc:
-      /* No default include directories.  You must specify all
-        include-file directories with -I.  */
-      cpp_opts->no_standard_includes = 1;
+      std_inc = false;
       break;
 
     case OPT_nostdincplusplus:
-      /* No default C++-specific include directories.  */
-      cpp_opts->no_standard_cplusplus_includes = 1;
+      std_cxx_inc = false;
       break;
 
     case OPT_o:
@@ -1356,7 +1431,7 @@ c_common_decode_option (argc, argv)
       break;
 
     case OPT_v:
-      cpp_opts->verbose = 1;
+      verbose = true;
       break;
     }
 
@@ -1384,6 +1459,10 @@ c_common_post_options ()
 
   sanitize_cpp_opts ();
 
+  register_include_chains (parse_in, sysroot, iprefix,
+                          std_inc, std_cxx_inc && c_language == clk_cplusplus,
+                          verbose);
+
   flag_inline_trees = 1;
 
   /* Use tree inlining if possible.  Function instrumentation is only
@@ -1607,6 +1686,18 @@ sanitize_cpp_opts ()
     = warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional);
 }
 
+/* Add include path with a prefix at the front of its name.  */
+static void
+add_prefixed_path (suffix, chain)
+     const char *suffix;
+     size_t chain;
+{
+  const char *prefix;
+
+  prefix = iprefix ? iprefix: cpp_GCC_INCLUDE_DIR;
+  add_path (concat (prefix, suffix), chain, 0);
+}
+
 /* Set the C 89 standard (with 1994 amendments if C94, without GNU
    extensions if ISO).  There is no concept of gnu94.  */
 static void
@@ -1808,6 +1899,7 @@ Switches:\n\
   fputs (_("\
   -f[no-]preprocessed       Treat the input file as already preprocessed\n\
   -ftabstop=<number>        Distance between tab stops for column reporting\n\
+  -isysroot <dir>           Set <dir> to be the system root directory\n\
   -P                        Do not generate #line directives\n\
   -remap                    Remap file names when including files\n\
   --help                    Display this information\n\
index 1fc78b0..c5db481 100644 (file)
@@ -1,3 +1,7 @@
+2003-03-01  Neil Booth  <neil@daikokuya.co.uk>
+
+       * Make-lang.in (CXX_C_OBJS): Update.
+
 2003-02-28  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/9892
index 7d8804c..da874b9 100644 (file)
@@ -79,7 +79,8 @@ g++-cross$(exeext): g++$(exeext)
 # The compiler itself.
 # Shared with C front end:
 CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
-       c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o
+       c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
+       c-incpath.o cppdefault.o
 
 # Language-specific object files.
 CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
index da4ddb5..cc96da7 100644 (file)
@@ -1,6 +1,6 @@
 /* CPP Library.
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000 Free Software Foundation, Inc.
+   1999, 2000, 2003 Free Software Foundation, Inc.
    Contributed by Per Bothner, 1994-95.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -19,15 +19,28 @@ 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.  */
 
-/* This file contains data definitions shared between cpplib and
-   tradcpp.  */
-
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
 #include "cppdefault.h"
 
+#ifndef STANDARD_INCLUDE_DIR
+#define STANDARD_INCLUDE_DIR "/usr/include"
+#endif
+
+#ifndef STANDARD_INCLUDE_COMPONENT
+#define STANDARD_INCLUDE_COMPONENT 0
+#endif
+
+#if defined (CROSS_COMPILE) && !defined (TARGET_SYSTEM_ROOT)
+# undef LOCAL_INCLUDE_DIR
+# undef SYSTEM_INCLUDE_DIR
+# undef STANDARD_INCLUDE_DIR
+#else
+# undef CROSS_INCLUDE_DIR
+#endif
+
 const struct default_include cpp_include_defaults[]
 #ifdef INCLUDE_DEFAULTS
 = INCLUDE_DEFAULTS;
index c87e27d..368e082 100644 (file)
@@ -1,6 +1,6 @@
 /* CPP Library.
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000 Free Software Foundation, Inc.
+   1999, 2000, 2003 Free Software Foundation, Inc.
    Contributed by Per Bothner, 1994-95.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -22,26 +22,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #ifndef GCC_CPPDEFAULT_H
 #define GCC_CPPDEFAULT_H
 
-/* This header contains declarations and/or #defines for all the
-   hard-wired defaults in cpp.  Note it's used by both cpplib and
-   tradcpp.  */
-
-#ifndef STANDARD_INCLUDE_DIR
-#define STANDARD_INCLUDE_DIR "/usr/include"
-#endif
-
-#ifndef STANDARD_INCLUDE_COMPONENT
-#define STANDARD_INCLUDE_COMPONENT 0
-#endif
-
-#if defined (CROSS_COMPILE) && !defined (TARGET_SYSTEM_ROOT)
-# undef LOCAL_INCLUDE_DIR
-# undef SYSTEM_INCLUDE_DIR
-# undef STANDARD_INCLUDE_DIR
-#else
-# undef CROSS_INCLUDE_DIR
-#endif
-
 /* This is the default list of directories to search for include files.
    It may be overridden by the various -I and -ixxx options.
 
@@ -57,11 +37,11 @@ struct default_include
   const char *const fname;     /* The name of the directory.  */
   const char *const component; /* The component containing the directory
                                   (see update_path in prefix.c) */
-  const int cplusplus;         /* Only look here if we're compiling C++.  */
-  const int cxx_aware;         /* Includes in this directory don't need to
+  const char cplusplus;                /* Only look here if we're compiling C++.  */
+  const char cxx_aware;                /* Includes in this directory don't need to
                                   be wrapped in extern "C" when compiling
                                   C++.  */
-  const int add_sysroot;       /* FNAME should be prefixed by
+  const char add_sysroot;      /* FNAME should be prefixed by
                                   cpp_SYSROOT.  */
 };
 
index 1f5d6c3..502e8a2 100644 (file)
@@ -1,6 +1,6 @@
 /* Part of CPP library.  (include file handling)
-   Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, 2003,
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998,
+   1999, 2000, 2001, 2002, 2003 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
@@ -90,7 +90,7 @@ struct include_file {
   const char *name;            /* actual path name of file */
   const char *header_name;     /* the original header found */
   const cpp_hashnode *cmacro;  /* macro, if any, preventing reinclusion.  */
-  const struct search_path *foundhere;
+  const struct cpp_path *foundhere;
                                /* location in search path where file was
                                   found, for #include_next and sysp.  */
   const unsigned char *buffer; /* pointer to cached file contents */
@@ -133,8 +133,8 @@ 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 *,
+                                        struct cpp_path *));
+static struct cpp_path *search_from PARAMS ((cpp_reader *,
                                                enum include_type));
 static struct include_file *
        find_include_file PARAMS ((cpp_reader *, const cpp_token *,
@@ -153,7 +153,6 @@ 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
@@ -161,7 +160,7 @@ static int remove_component_p       PARAMS ((const char *));
    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.
+   simplify_path.  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.
 
@@ -208,8 +207,7 @@ _cpp_never_reread (file)
 }
 
 /* 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.  */
+   create an entry if none exists.  */
 static splay_tree_node
 find_or_create_entry (pfile, fname)
      cpp_reader *pfile;
@@ -218,8 +216,15 @@ find_or_create_entry (pfile, fname)
   splay_tree_node node;
   struct include_file *file;
   char *name = xstrdup (fname);
+  int saved_errno = 0;
+
+  if (pfile->cb.simplify_path)
+    {
+      errno = 0;
+      (pfile->cb.simplify_path) (name);
+      saved_errno = errno;
+    }
 
-  _cpp_simplify_pathname (name);
   node = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
   if (node)
     free (name);
@@ -228,7 +233,7 @@ find_or_create_entry (pfile, fname)
       file = xcnew (struct include_file);
       file->name = name;
       file->header_name = name;
-      file->err_no = errno;
+      file->err_no = saved_errno;
       node = splay_tree_insert (pfile->all_include_files,
                                (splay_tree_key) file->name,
                                (splay_tree_value) file);
@@ -337,7 +342,9 @@ validate_pch (pfile, filename, pchname)
     file->pch = pfile->cb.valid_pch (pfile, pchname, file->fd);
   if (INCLUDE_PCH_P (file))
     {
-      file->header_name = _cpp_simplify_pathname (xstrdup (filename));
+      char *f = xstrdup (filename);
+      (pfile->cb.simplify_path) (f);
+      file->header_name = f;
       return file;
     }
   close (file->fd);
@@ -640,7 +647,7 @@ cpp_included (pfile, fname)
      cpp_reader *pfile;
      const char *fname;
 {
-  struct search_path *path;
+  struct cpp_path *path;
   char *name, *n;
   splay_tree_node nd;
 
@@ -653,7 +660,7 @@ cpp_included (pfile, fname)
 
   /* 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)
+  for (path = pfile->quote_include; path; path = path->next)
     {
       memcpy (name, path->name, path->len);
       name[path->len] = '/';
@@ -682,7 +689,7 @@ find_include_file (pfile, header, type)
      enum include_type type;
 {
   const char *fname = (const char *) header->val.str.text;
-  struct search_path *path;
+  struct cpp_path *path;
   struct include_file *file;
   char *name, *n;
 
@@ -695,7 +702,7 @@ find_include_file (pfile, header, type)
   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);
+    path = pfile->bracket_include;
   else
     path = search_from (pfile, type);
 
@@ -905,7 +912,7 @@ _cpp_pop_file_buffer (pfile, inc)
 
    If we're handling -include or -imacros, use the "" chain, but with
    the preprocessor's cwd prepended.  */
-static struct search_path *
+static struct cpp_path *
 search_from (pfile, type)
      cpp_reader *pfile;
      enum include_type type;
@@ -917,9 +924,9 @@ search_from (pfile, type)
   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);
+  /* Ignore the current file's directory?  */
+  if (pfile->quote_ignores_source_dir)
+    return pfile->quote_include;
 
   if (! buffer->search_cached)
     {
@@ -931,14 +938,14 @@ search_from (pfile, type)
        {
          /* We don't guarantee NAME is null-terminated.  This saves
             allocating and freeing memory.  Drop a trailing '/'.  */
-         buffer->dir.name = buffer->inc->name;
+         buffer->dir.name = (char *) buffer->inc->name;
          if (dlen > 1)
            dlen--;
        }
       else
        {
        use_cwd:
-         buffer->dir.name = ".";
+         buffer->dir.name = (char *) ".";
          dlen = 1;
        }
 
@@ -946,7 +953,7 @@ search_from (pfile, type)
        pfile->max_include_len = dlen;
 
       buffer->dir.len = dlen;
-      buffer->dir.next = CPP_OPTION (pfile, quote_include);
+      buffer->dir.next = pfile->quote_include;
       buffer->dir.sysp = pfile->map->sysp;
     }
 
@@ -1089,7 +1096,7 @@ static char *
 remap_filename (pfile, name, loc)
      cpp_reader *pfile;
      char *name;
-     struct search_path *loc;
+     struct cpp_path *loc;
 {
   struct file_name_map *map;
   const char *from, *p;
@@ -1138,158 +1145,29 @@ remap_filename (pfile, name, loc)
   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);
-}
+/* 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.
 
-/* 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;
+   If BRACKET does not lie in the QUOTE chain, it is set to QUOTE.  */
+void
+cpp_set_include_chains (pfile, quote, bracket, quote_ignores_source_dir)
+     cpp_reader *pfile;
+     cpp_path *quote, *bracket;
+     int quote_ignores_source_dir;
 {
-#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
+  pfile->quote_include = quote;
+  pfile->bracket_include = quote;
+  pfile->quote_ignores_source_dir = quote_ignores_source_dir;
+  pfile->max_include_len = 0;
 
-  /* Remove redundant leading /s.  */
-  if (*from == '/')
+  for (; quote; quote = quote->next)
     {
-      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++;
-       }
+      quote->name_map = NULL;
+      quote->len = strlen (quote->name);
+      if (quote->len > pfile->max_include_len)
+       pfile->max_include_len = quote->len;
+      if (quote == bracket)
+       pfile->bracket_include = bracket;
     }
-
-  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  */
 }
index 9aff511..16aba08 100644 (file)
@@ -1,5 +1,5 @@
 /* Part of CPP library.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
    Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify it
@@ -130,26 +130,6 @@ extern unsigned char *_cpp_unaligned_alloc PARAMS ((cpp_reader *, size_t));
 #define BUFF_FRONT(BUFF) ((BUFF)->cur)
 #define BUFF_LIMIT(BUFF) ((BUFF)->limit)
 
-/* List of directories to look for include files in.  */
-struct search_path
-{
-  struct search_path *next;
-
-  /* NOTE: NAME may not be null terminated for the case of the current
-     file's directory!  */
-  const char *name;
-  unsigned int len;
-  /* We use these to tell if the directory mentioned here is a duplicate
-     of an earlier directory on the search path.  */
-  ino_t ino;
-  dev_t dev;
-  /* Nonzero if it is a system include directory.  */
-  int sysp;
-  /* Mapping of file names for this directory.  Only used on MS-DOS
-     and related platforms.  */
-  struct file_name_map *name_map;
-};
-
 /* #include types.  */
 enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE};
 
@@ -324,7 +304,7 @@ struct cpp_buffer
 
   /* The directory of the this buffer's file.  Its NAME member is not
      allocated, so we don't need to worry about freeing it.  */
-  struct search_path dir;
+  struct cpp_path dir;
 
   /* Used for buffer overlays by cpptrad.c.  */
   const uchar *saved_cur, *saved_rlimit;
@@ -369,6 +349,10 @@ struct cpp_reader
      _cpp_maybe_push_include_file has yet to restore the line map.  */
   struct pending_option **next_include_file;
 
+  /* Search paths for include files.  */
+  struct cpp_path *quote_include;      /* "" */
+  struct cpp_path *bracket_include;    /* <> */
+
   /* Multiple include optimisation.  */
   const cpp_hashnode *mi_cmacro;
   const cpp_hashnode *mi_ind_cmacro;
@@ -441,6 +425,10 @@ struct cpp_reader
   /* Used when doing preprocessed output.  */
   struct printer print;
 
+  /* Nonzero means don't look for #include "foo" the source-file
+     directory.  */
+  unsigned char quote_ignores_source_dir;
+
   /* Whether cpplib owns the hashtable.  */
   unsigned char our_hashtable;
 
@@ -521,7 +509,6 @@ extern void _cpp_destroy_hashtable  PARAMS ((cpp_reader *));
 /* In cppfiles.c */
 extern void _cpp_fake_include          PARAMS ((cpp_reader *, const char *));
 extern void _cpp_never_reread          PARAMS ((struct include_file *));
-extern char *_cpp_simplify_pathname    PARAMS ((char *));
 extern bool _cpp_read_file             PARAMS ((cpp_reader *, const char *));
 extern bool _cpp_execute_include       PARAMS ((cpp_reader *,
                                                 const cpp_token *,
index 40b5059..2068ba1 100644 (file)
@@ -1,6 +1,6 @@
 /* CPP Library.
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
    Contributed by Per Bothner, 1994-95.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -25,25 +25,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "tm.h"
 #include "cpplib.h"
 #include "cpphash.h"
-#include "prefix.h"
 #include "intl.h"
 #include "mkdeps.h"
-#include "cppdefault.h"
-
-/* Windows does not natively support inodes, and neither does MSDOS.
-   Cygwin's emulation can generate non-unique inodes, so don't use it.
-   VMS has non-numeric inodes.  */
-#ifdef VMS
-# define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
-# define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
-#else
-# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
-#  define INO_T_EQ(A, B) 0
-# else
-#  define INO_T_EQ(A, B) ((A) == (B))
-# endif
-# define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
-#endif
 
 /* Internal structures and prototypes.  */
 
@@ -64,12 +47,6 @@ struct pending_option
 struct cpp_pending
 {
   struct pending_option *directive_head, *directive_tail;
-
-  struct search_path *quote_head, *quote_tail;
-  struct search_path *brack_head, *brack_tail;
-  struct search_path *systm_head, *systm_tail;
-  struct search_path *after_head, *after_tail;
-
   struct pending_option *imacros_head, *imacros_tail;
   struct pending_option *include_head, *include_tail;
 };
@@ -88,26 +65,12 @@ struct cpp_pending
   } while (0)
 #endif
 
-static void path_include               PARAMS ((cpp_reader *,
-                                                const char *, int));
 static void init_library               PARAMS ((void));
 static void init_builtins              PARAMS ((cpp_reader *));
 static void mark_named_operators       PARAMS ((cpp_reader *));
-static void append_include_chain       PARAMS ((cpp_reader *,
-                                                char *, int, int));
-static struct search_path * remove_dup_dir     PARAMS ((cpp_reader *,
-                                                struct search_path *,
-                                                struct search_path **));
-static struct search_path * remove_dup_nonsys_dirs PARAMS ((cpp_reader *,
-                                                struct search_path **,
-                                                struct search_path *));
-static struct search_path * remove_dup_dirs PARAMS ((cpp_reader *,
-                                                struct search_path **));
-static void merge_include_chains       PARAMS ((cpp_reader *));
 static bool push_include               PARAMS ((cpp_reader *,
                                                 struct pending_option *));
 static void free_chain                 PARAMS ((struct pending_option *));
-static void init_standard_includes     PARAMS ((cpp_reader *));
 static void read_original_filename     PARAMS ((cpp_reader *));
 static void new_pending_directive      PARAMS ((struct cpp_pending *,
                                                 const char *,
@@ -115,10 +78,6 @@ static void new_pending_directive   PARAMS ((struct cpp_pending *,
 static int parse_option                        PARAMS ((const char *));
 static void post_options               PARAMS ((cpp_reader *));
 
-/* Fourth argument to append_include_chain: chain to use.
-   Note it's never asked to append to the quote chain.  */
-enum { BRACKET = 0, SYSTEM, AFTER };
-
 /* If we have designated initializers (GCC >2.7) these tables can be
    initialized, constant data.  Otherwise, they have to be filled in at
    runtime.  */
@@ -152,277 +111,6 @@ END
 #undef END
 #undef TRIGRAPH_MAP
 
-/* Read ENV_VAR for a colon-separated list of file names; and
-   add all the names to the search path for include files.  */
-static void
-path_include (pfile, env_var, path)
-     cpp_reader *pfile;
-     const char *env_var;
-     int path;
-{
-  char *p, *q, *name;
-
-  GET_ENVIRONMENT (q, env_var);
-  if (!q)
-    return;
-
-  for (p = q; *q; p = q + 1)
-    {
-      /* Find the end of this name.  */
-      q = p;
-      while (*q != 0 && *q != PATH_SEPARATOR) q++;
-      if (q == p)
-       {
-         /* An empty name in the path stands for the current directory.  */
-         name = (char *) xmalloc (2);
-         name[0] = '.';
-         name[1] = 0;
-       }
-      else
-       {
-         /* Otherwise use the directory that is named.  */
-         name = (char *) xmalloc (q - p + 1);
-         memcpy (name, p, q - p);
-         name[q - p] = 0;
-       }
-
-      append_include_chain (pfile, name, path, path == SYSTEM);
-    }
-}
-
-/* Append DIR to include path PATH.  DIR must be allocated on the
-   heap; this routine takes responsibility for freeing it.  CXX_AWARE
-   is nonzero if the header contains extern "C" guards for C++,
-   otherwise it is zero.  */
-static void
-append_include_chain (pfile, dir, path, cxx_aware)
-     cpp_reader *pfile;
-     char *dir;
-     int path;
-     int cxx_aware;
-{
-  struct cpp_pending *pend = CPP_OPTION (pfile, pending);
-  struct search_path *new;
-  struct stat st;
-  unsigned int len;
-
-  if (*dir == '\0')
-    {
-      free (dir);
-      dir = xstrdup (".");
-    }
-  _cpp_simplify_pathname (dir);
-
-  if (stat (dir, &st))
-    {
-      /* Dirs that don't exist are silently ignored.  */
-      if (errno != ENOENT)
-       cpp_errno (pfile, DL_ERROR, dir);
-      else if (CPP_OPTION (pfile, verbose))
-       fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"), dir);
-      free (dir);
-      return;
-    }
-
-  if (!S_ISDIR (st.st_mode))
-    {
-      cpp_error_with_line (pfile, DL_ERROR, 0, 0, "%s: Not a directory", dir);
-      free (dir);
-      return;
-    }
-
-  len = strlen (dir);
-  if (len > pfile->max_include_len)
-    pfile->max_include_len = len;
-
-  new = (struct search_path *) xmalloc (sizeof (struct search_path));
-  new->name = dir;
-  new->len = len;
-  INO_T_COPY (new->ino, st.st_ino);
-  new->dev  = st.st_dev;
-  /* Both systm and after include file lists should be treated as system
-     include files since these two lists are really just a concatenation
-     of one "system" list.  */
-  if (path == SYSTEM || path == AFTER)
-    new->sysp = cxx_aware ? 1 : 2;
-  else
-    new->sysp = 0;
-  new->name_map = NULL;
-  new->next = NULL;
-
-  switch (path)
-    {
-    case BRACKET:      APPEND (pend, brack, new); break;
-    case SYSTEM:       APPEND (pend, systm, new); break;
-    case AFTER:                APPEND (pend, after, new); break;
-    }
-}
-
-/* Handle a duplicated include path.  PREV is the link in the chain
-   before the duplicate, or NULL if the duplicate is at the head of
-   the chain.  The duplicate is removed from the chain and freed.
-   Returns PREV.  */
-static struct search_path *
-remove_dup_dir (pfile, prev, head_ptr)
-     cpp_reader *pfile;
-     struct search_path *prev;
-     struct search_path **head_ptr;
-{
-  struct search_path *cur;
-
-  if (prev != NULL)
-    {
-      cur = prev->next;
-      prev->next = cur->next;
-    }
-  else
-    {
-      cur = *head_ptr;
-      *head_ptr = cur->next;
-    }
-
-  if (CPP_OPTION (pfile, verbose))
-    fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), cur->name);
-
-  free ((PTR) cur->name);
-  free (cur);
-
-  return prev;
-}
-
-/* Remove duplicate non-system directories for which there is an equivalent
-   system directory latter in the chain.  The range for removal is between
-   *HEAD_PTR and END.  Returns the directory before END, or NULL if none.
-   This algorithm is quadratic in the number system directories, which is
-   acceptable since there aren't usually that many of them.  */
-static struct search_path *
-remove_dup_nonsys_dirs (pfile, head_ptr, end)
-     cpp_reader *pfile;
-     struct search_path **head_ptr;
-     struct search_path *end;
-{
-  int sysdir = 0;
-  struct search_path *prev = NULL, *cur, *other;
-
-  for (cur = *head_ptr; cur; cur = cur->next)
-    {
-      if (cur->sysp)
-       {
-         sysdir = 1;
-         for (other = *head_ptr, prev = NULL;
-              other != end;
-              other = other ? other->next : *head_ptr)
-           {
-             if (!other->sysp
-                 && INO_T_EQ (cur->ino, other->ino)
-                 && cur->dev == other->dev)
-               {
-                 other = remove_dup_dir (pfile, prev, head_ptr);
-                 if (CPP_OPTION (pfile, verbose))
-                   fprintf (stderr,
-  _("  as it is a non-system directory that duplicates a system directory\n"));
-               }
-             prev = other;
-           }
-       }
-    }
-
-  if (!sysdir)
-    for (cur = *head_ptr; cur != end; cur = cur->next)
-      prev = cur;
-
-  return prev;
-}
-
-/* Remove duplicate directories from a chain.  Returns the tail of the
-   chain, or NULL if the chain is empty.  This algorithm is quadratic
-   in the number of -I switches, which is acceptable since there
-   aren't usually that many of them.  */
-static struct search_path *
-remove_dup_dirs (pfile, head_ptr)
-     cpp_reader *pfile;
-     struct search_path **head_ptr;
-{
-  struct search_path *prev = NULL, *cur, *other;
-
-  for (cur = *head_ptr; cur; cur = cur->next)
-    {
-      for (other = *head_ptr; other != cur; other = other->next)
-       if (INO_T_EQ (cur->ino, other->ino) && cur->dev == other->dev)
-         {
-           cur = remove_dup_dir (pfile, prev, head_ptr);
-           break;
-         }
-      prev = cur;
-    }
-
-  return prev;
-}
-
-/* Merge the four include chains together in the order quote, bracket,
-   system, after.  Remove duplicate dirs (as determined by
-   INO_T_EQ()).  The system_include and after_include chains are never
-   referred to again after this function; all access is through the
-   bracket_include path.  */
-static void
-merge_include_chains (pfile)
-     cpp_reader *pfile;
-{
-  struct search_path *quote, *brack, *systm, *qtail;
-
-  struct cpp_pending *pend = CPP_OPTION (pfile, pending);
-
-  quote = pend->quote_head;
-  brack = pend->brack_head;
-  systm = pend->systm_head;
-  qtail = pend->quote_tail;
-
-  /* Paste together bracket, system, and after include chains.  */
-  if (systm)
-    pend->systm_tail->next = pend->after_head;
-  else
-    systm = pend->after_head;
-
-  if (brack)
-    pend->brack_tail->next = systm;
-  else
-    brack = systm;
-
-  /* This is a bit tricky.  First we drop non-system dupes of system
-     directories from the merged bracket-include list.  Next we drop
-     dupes from the bracket and quote include lists.  Then we drop
-     non-system dupes from the merged quote-include list.  Finally,
-     if qtail and brack are the same directory, we cut out brack and
-     move brack up to point to qtail.
-
-     We can't just merge the lists and then uniquify them because
-     then we may lose directories from the <> search path that should
-     be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux.  It is however
-     safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
-     -Ibar -I- -Ifoo -Iquux.  */
-
-  remove_dup_nonsys_dirs (pfile, &brack, systm);
-  remove_dup_dirs (pfile, &brack);
-
-  if (quote)
-    {
-      qtail = remove_dup_dirs (pfile, &quote);
-      qtail->next = brack;
-
-      qtail = remove_dup_nonsys_dirs (pfile, &quote, brack);
-
-      /* If brack == qtail, remove brack as it's simpler.  */
-      if (qtail && brack && INO_T_EQ (qtail->ino, brack->ino)
-         && qtail->dev == brack->dev)
-       brack = remove_dup_dir (pfile, qtail, &quote);
-    }
-  else
-    quote = brack;
-
-  CPP_OPTION (pfile, quote_include) = quote;
-  CPP_OPTION (pfile, bracket_include) = brack;
-}
-
 /* A set of booleans indicating what CPP features each source language
    requires.  */
 struct lang_flags
@@ -529,7 +217,6 @@ cpp_create_reader (lang)
   CPP_OPTION (pfile, warn_endif_labels) = 1;
   CPP_OPTION (pfile, warn_deprecated) = 1;
   CPP_OPTION (pfile, warn_long_long) = !CPP_OPTION (pfile, c99);
-  CPP_OPTION (pfile, sysroot) = cpp_SYSROOT;
 
   CPP_OPTION (pfile, pending) =
     (struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
@@ -588,7 +275,6 @@ void
 cpp_destroy (pfile)
      cpp_reader *pfile;
 {
-  struct search_path *dir, *dirn;
   cpp_context *context, *contextn;
   tokenrun *run, *runn;
 
@@ -628,13 +314,6 @@ cpp_destroy (pfile)
        free (run);
     }
 
-  for (dir = CPP_OPTION (pfile, quote_include); dir; dir = dirn)
-    {
-      dirn = dir->next;
-      free ((PTR) dir->name);
-      free (dir);
-    }
-
   for (context = pfile->base_context.next; context; context = contextn)
     {
       contextn = context->next;
@@ -751,69 +430,6 @@ init_builtins (pfile)
     (*pfile->cb.register_builtins) (pfile);
 }
 
-/* And another subroutine.  This one sets up the standard include path.  */
-static void
-init_standard_includes (pfile)
-     cpp_reader *pfile;
-{
-  const struct default_include *p;
-  const char *specd_prefix = CPP_OPTION (pfile, include_prefix);
-  int default_len, specd_len;
-  char *default_prefix;
-
-  /* Search "translated" versions of GNU directories.
-     These have /usr/local/lib/gcc... replaced by specd_prefix.  */
-  default_len = 0;
-  specd_len = 0;
-  default_prefix = NULL;
-  if (specd_prefix != 0 && cpp_GCC_INCLUDE_DIR_len)
-    {
-      /* Remove the `include' from /usr/local/lib/gcc.../include.
-        GCC_INCLUDE_DIR will always end in /include.  */
-      default_len = cpp_GCC_INCLUDE_DIR_len;
-      default_prefix = (char *) alloca (default_len + 1);
-      specd_len = strlen (specd_prefix);
-
-      memcpy (default_prefix, cpp_GCC_INCLUDE_DIR, default_len);
-      default_prefix[default_len] = '\0';
-    }
-
-  for (p = cpp_include_defaults; p->fname; p++)
-    {
-      /* Some standard dirs are only for C++.  */
-      if (!p->cplusplus
-         || (CPP_OPTION (pfile, cplusplus)
-             && !CPP_OPTION (pfile, no_standard_cplusplus_includes)))
-       {
-         char *str;
-
-         /* Should this dir start with the sysroot?  */
-         if (p->add_sysroot && CPP_OPTION (pfile, sysroot))
-           str = concat (CPP_OPTION (pfile, sysroot), p->fname, NULL);
-
-         /* Does this dir start with the prefix?  */
-         else if (default_len
-                  && !strncmp (p->fname, default_prefix, default_len))
-           {
-             /* Yes; change prefix and add to search list.  */
-             int flen = strlen (p->fname);
-             int this_len = specd_len + flen - default_len;
-
-             str = (char *) xmalloc (this_len + 1);
-             memcpy (str, specd_prefix, specd_len);
-             memcpy (str + specd_len,
-                     p->fname + default_len,
-                     flen - default_len + 1);
-           }
-
-         else
-           str = update_path (p->fname, p->component);
-
-         append_include_chain (pfile, str, SYSTEM, p->cxx_aware);
-       }
-    }
-}
-
 /* Pushes a command line -imacro and -include file indicated by P onto
    the buffer stack.  Returns nonzero if successful.  */
 static bool
@@ -925,11 +541,6 @@ cpp_read_main_file (pfile, fname, table)
      const char *fname;
      hash_table *table;
 {
-  static const char *const lang_env_vars[] =
-    { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
-      "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
-  size_t lang;
-
   sanity_checks (pfile);
 
   post_options (pfile);
@@ -939,35 +550,6 @@ cpp_read_main_file (pfile, fname, table)
      hashtable is deferred until now.  */
   _cpp_init_hashtable (pfile, table);
 
-  /* Several environment variables may add to the include search path.
-     CPATH specifies an additional list of directories to be searched
-     as if specified with -I, while C_INCLUDE_PATH, CPLUS_INCLUDE_PATH,
-     etc. specify an additional list of directories to be searched as
-     if specified with -isystem, for the language indicated.  */
-  path_include (pfile, "CPATH", BRACKET);
-  lang = (CPP_OPTION (pfile, objc) << 1) + CPP_OPTION (pfile, cplusplus);
-  path_include (pfile, lang_env_vars[lang], SYSTEM);
-
-  /* Set up the include search path now.  */
-  if (! CPP_OPTION (pfile, no_standard_includes))
-    init_standard_includes (pfile);
-
-  merge_include_chains (pfile);
-
-  /* With -v, print the list of dirs to search.  */
-  if (CPP_OPTION (pfile, verbose))
-    {
-      struct search_path *l;
-      fprintf (stderr, _("#include \"...\" search starts here:\n"));
-      for (l = CPP_OPTION (pfile, quote_include); l; l = l->next)
-       {
-         if (l == CPP_OPTION (pfile, bracket_include))
-           fprintf (stderr, _("#include <...> search starts here:\n"));
-         fprintf (stderr, " %s\n", l->name);
-       }
-      fprintf (stderr, _("End of search list.\n"));
-    }
-
   if (CPP_OPTION (pfile, deps.style) != DEPS_NONE)
     {
       if (!pfile->deps)
@@ -1149,26 +731,17 @@ new_pending_directive (pend, text, handler)
    I.e. a const string initializer with parens around it.  That is
    what N_("string") resolves to, so we make no_* be macros instead.  */
 #define no_ass N_("assertion missing after %s")
-#define no_dir N_("directory name missing after %s")
 #define no_fil N_("file name missing after %s")
 #define no_mac N_("macro name missing after %s")
-#define no_pth N_("path name missing after %s")
 
 /* This is the list of all command line options, with the leading
    "-" removed.  It must be sorted in ASCII collating order.  */
 #define COMMAND_LINE_OPTIONS                                                  \
   DEF_OPT("A",                        no_ass, OPT_A)                          \
   DEF_OPT("D",                        no_mac, OPT_D)                          \
-  DEF_OPT("I",                        no_dir, OPT_I)                          \
   DEF_OPT("U",                        no_mac, OPT_U)                          \
-  DEF_OPT("idirafter",                no_dir, OPT_idirafter)                  \
   DEF_OPT("imacros",                  no_fil, OPT_imacros)                    \
-  DEF_OPT("include",                  no_fil, OPT_include)                    \
-  DEF_OPT("iprefix",                  no_pth, OPT_iprefix)                    \
-  DEF_OPT("isysroot",                 no_dir, OPT_isysroot)                   \
-  DEF_OPT("isystem",                  no_dir, OPT_isystem)                    \
-  DEF_OPT("iwithprefix",              no_dir, OPT_iwithprefix)                \
-  DEF_OPT("iwithprefixbefore",        no_dir, OPT_iwithprefixbefore)
+  DEF_OPT("include",                  no_fil, OPT_include)
 
 #define DEF_OPT(text, msg, code) code,
 enum opt_code
@@ -1305,14 +878,6 @@ cpp_handle_option (pfile, argc, argv)
        case OPT_D:
          new_pending_directive (pend, arg, cpp_define);
          break;
-       case OPT_iprefix:
-         CPP_OPTION (pfile, include_prefix) = arg;
-         CPP_OPTION (pfile, include_prefix_len) = strlen (arg);
-         break;
-
-       case OPT_isysroot:
-         CPP_OPTION (pfile, sysroot) = arg;
-         break;
 
        case OPT_A:
          if (arg[0] == '-')
@@ -1340,37 +905,6 @@ cpp_handle_option (pfile, argc, argv)
        case OPT_U:
          new_pending_directive (pend, arg, cpp_undef);
          break;
-       case OPT_I:           /* Add directory to path for includes.  */
-         if (!strcmp (arg, "-"))
-           {
-             /* -I- means:
-                Use the preceding -I directories for #include "..."
-                but not #include <...>.
-                Don't search the directory of the present file
-                for #include "...".  (Note that -I. -I- is not the same as
-                the default setup; -I. uses the compiler's working dir.)  */
-             if (! CPP_OPTION (pfile, ignore_srcdir))
-               {
-                 pend->quote_head = pend->brack_head;
-                 pend->quote_tail = pend->brack_tail;
-                 pend->brack_head = 0;
-                 pend->brack_tail = 0;
-                 CPP_OPTION (pfile, ignore_srcdir) = 1;
-               }
-             else
-               {
-                 cpp_error (pfile, DL_ERROR, "-I- specified twice");
-                 return argc;
-               }
-           }
-         else
-           append_include_chain (pfile, xstrdup (arg), BRACKET, 0);
-         break;
-       case OPT_isystem:
-         /* Add directory to beginning of system include path, as a system
-            include directory.  */
-         append_include_chain (pfile, xstrdup (arg), SYSTEM, 0);
-         break;
        case OPT_include:
        case OPT_imacros:
          {
@@ -1385,71 +919,11 @@ cpp_handle_option (pfile, argc, argv)
              APPEND (pend, imacros, o);
          }
          break;
-       case OPT_iwithprefix:
-         /* Add directory to end of path for includes,
-            with the default prefix at the front of its name.  */
-         /* fall through */
-       case OPT_iwithprefixbefore:
-         /* Add directory to main path for includes,
-            with the default prefix at the front of its name.  */
-         {
-           char *fname;
-           int len;
-
-           len = strlen (arg);
-
-           if (CPP_OPTION (pfile, include_prefix) != 0)
-             {
-               size_t ipl = CPP_OPTION (pfile, include_prefix_len);
-               fname = xmalloc (ipl + len + 1);
-               memcpy (fname, CPP_OPTION (pfile, include_prefix), ipl);
-               memcpy (fname + ipl, arg, len + 1);
-             }
-           else if (cpp_GCC_INCLUDE_DIR_len)
-             {
-               fname = xmalloc (cpp_GCC_INCLUDE_DIR_len + len + 1);
-               memcpy (fname, cpp_GCC_INCLUDE_DIR, cpp_GCC_INCLUDE_DIR_len);
-               memcpy (fname + cpp_GCC_INCLUDE_DIR_len, arg, len + 1);
-             }
-           else
-             fname = xstrdup (arg);
-
-           append_include_chain (pfile, fname,
-                         opt_code == OPT_iwithprefix ? SYSTEM: BRACKET, 0);
-         }
-         break;
-       case OPT_idirafter:
-         /* Add directory to end of path for includes.  */
-         append_include_chain (pfile, xstrdup (arg), AFTER, 0);
-         break;
        }
     }
   return i + 1;
 }
 
-/* Handle command-line options in (argc, argv).
-   Can be called multiple times, to handle multiple sets of options.
-   Returns if an unrecognized option is seen.
-   Returns number of strings consumed.  */
-int
-cpp_handle_options (pfile, argc, argv)
-     cpp_reader *pfile;
-     int argc;
-     char **argv;
-{
-  int i;
-  int strings_processed;
-
-  for (i = 0; i < argc; i += strings_processed)
-    {
-      strings_processed = cpp_handle_option (pfile, argc - i, argv + i);
-      if (strings_processed == 0)
-       break;
-    }
-
-  return i;
-}
-
 static void
 post_options (pfile)
      cpp_reader *pfile;
index 3225627..384dd20 100644 (file)
@@ -39,6 +39,7 @@ typedef struct cpp_string cpp_string;
 typedef struct cpp_hashnode cpp_hashnode;
 typedef struct cpp_macro cpp_macro;
 typedef struct cpp_callbacks cpp_callbacks;
+typedef struct cpp_path cpp_path;
 
 struct answer;
 struct file_name_map_list;
@@ -224,29 +225,13 @@ struct cpp_options
   /* Pending options - -D, -U, -A, -I, -ixxx.  */
   struct cpp_pending *pending;
 
-  /* Search paths for include files.  */
-  struct search_path *quote_include;   /* "" */
-  struct search_path *bracket_include;  /* <> */
-
   /* Map between header names and file names, used only on DOS where
      file names are limited in length.  */
   struct file_name_map_list *map_list;
 
-  /* Directory prefix that should replace `/usr/lib/gcc-lib/TARGET/VERSION'
-     in the standard include file directories.  */
-  const char *include_prefix;
-  unsigned int include_prefix_len;
-
-  /* Directory prefix for system include directories in the standard search
-     path.  */
-  const char *sysroot;
-
   /* The language we're preprocessing.  */
   enum c_lang lang;
 
-  /* Non-0 means -v, so print the full set of include dirs.  */
-  unsigned char verbose;
-
   /* Nonzero means use extra default include directories for C++.  */
   unsigned char cplusplus;
 
@@ -332,10 +317,6 @@ struct cpp_options
   /* Nonzero means don't output line number information.  */
   unsigned char no_line_commands;
 
-  /* Nonzero means -I- has been seen, so don't look for #include "foo"
-     the source-file directory.  */
-  unsigned char ignore_srcdir;
-
   /* Zero means dollar signs are punctuation.  */
   unsigned char dollars_in_ident;
 
@@ -358,12 +339,6 @@ struct cpp_options
      bother trying to do macro expansion and whatnot.  */
   unsigned char preprocessed;
 
-  /* Nonzero disables all the standard directories for headers.  */
-  unsigned char no_standard_includes;
-
-  /* Nonzero disables the C++-specific standard directories for headers.  */
-  unsigned char no_standard_cplusplus_includes;
-
   /* Nonzero means dump macros in some fashion - see above.  */
   unsigned char dump_macros;
 
@@ -427,6 +402,7 @@ struct cpp_callbacks
   void (*undef) PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
   void (*ident) PARAMS ((cpp_reader *, unsigned int, const cpp_string *));
   void (*def_pragma) PARAMS ((cpp_reader *, unsigned int));
+  void (*simplify_path) PARAMS ((char *));
   /* Called when the client has a chance to properly register
      built-ins with cpp_define() and cpp_assert().  */
   void (*register_builtins) PARAMS ((cpp_reader *));
@@ -434,6 +410,30 @@ struct cpp_callbacks
   void (*read_pch) PARAMS ((cpp_reader *, const char *, int, const char *));
 };
 
+/* Chain of directories to look for include files in.  */
+struct cpp_path
+{
+  /* NULL-terminated singly-linked list.  */
+  struct cpp_path *next;
+
+  /* NAME need not be NUL-terminated once inside cpplib.  */
+  char *name;
+  unsigned int len;
+
+  /* One if a system header, two if a system header that has extern
+     "C" guards for C++.  */
+  unsigned char sysp;
+
+  /* Mapping of file names for this directory for MS-DOS and
+     related platforms.  */
+  struct file_name_map *name_map;
+    
+  /* The C front end uses these to recognize duplicated
+     directories in the search path.  */
+  ino_t ino;
+  dev_t dev;
+};
+
 /* Name under which this program was invoked.  */
 extern const char *progname;
 
@@ -526,6 +526,10 @@ extern void cpp_add_dependency_target PARAMS ((cpp_reader *,
                                               const char * target,
                                               int quote));
 
+/* Set the include paths.  */
+extern void cpp_set_include_chains PARAMS ((cpp_reader *, cpp_path *,
+                                           cpp_path *, int));
+
 /* Call these to get pointers to the options and callback structures
    for a given reader.  These pointers are good until you call
    cpp_finish on that reader.  You can either edit the callbacks
@@ -536,12 +540,9 @@ extern const struct line_maps *cpp_get_line_maps PARAMS ((cpp_reader *));
 extern cpp_callbacks *cpp_get_callbacks PARAMS ((cpp_reader *));
 extern void cpp_set_callbacks PARAMS ((cpp_reader *, cpp_callbacks *));
 
-/* Now call cpp_handle_option[s] to handle 1[or more] switches.  The
-   return value is the number of arguments used.  If
-   cpp_handle_options returns without using all arguments, it couldn't
-   understand the next switch.  Options processing is not completed
+/* Now call cpp_handle_option to handle 1 switch.  The return value is
+   the number of arguments used.  Options processing is not completed
    until you call cpp_finish_options.  */
-extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
 extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
 
 /* This function reads the file, but does not start preprocessing.  It
index 10cc381..107fe5d 100644 (file)
@@ -82,8 +82,10 @@ the other C-like languages: @file{c-common.c},
 @file{c-pragma.c},
 @file{c-semantics.c},
 @file{c-lex.c},
+@file{c-incpath.c}
 @file{c-common.h},
 @file{c-dump.h},
+@file{c-incpath.h}
 and
 @file{c-pragma.h},
 
index d722450..305a868 100644 (file)
@@ -1,6 +1,6 @@
 /* fix-header.c - Make C header file suitable for C++.
    Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2003 Free Software Foundation, Inc.
 
 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
@@ -78,6 +78,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "obstack.h"
 #include "scan.h"
 #include "cpplib.h"
+#include "c-incpath.h"
 
 static void v_fatal PARAMS ((const char *, va_list)) ATTRIBUTE_PRINTF (1,0) ATTRIBUTE_NORETURN;
 static void fatal PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
@@ -616,7 +617,7 @@ read_scan_file (in_fname, argc, argv)
   cpp_callbacks *cb;
   cpp_options *options;
   struct fn_decl *fn;
-  int i;
+  int i, strings_processed;
   struct symbol_list *cur_symbols;
 
   obstack_init (&scan_file_obstack);
@@ -624,6 +625,7 @@ read_scan_file (in_fname, argc, argv)
   scan_in = cpp_create_reader (CLK_GNUC89);
   cb = cpp_get_callbacks (scan_in);
   cb->file_change = cb_file_change;
+  cb->simplify_path = simplify_path;
 
   /* We are going to be scanning a header file out of its proper context,
      so ignore warnings and errors.  */
@@ -631,12 +633,32 @@ read_scan_file (in_fname, argc, argv)
   options->inhibit_warnings = 1;
   options->inhibit_errors = 1;
 
-  i = cpp_handle_options (scan_in, argc, argv);
+  for (i = 0; i < argc; i += strings_processed)
+    {
+      if (argv[i][0] == 'I')
+       {
+         if (argv[i][1] != '\0')
+           strings_processed = 1, add_path (argv[i] + 1, BRACKET, false);
+         else if (i + 1 == argc)
+           strings_processed = 0;
+         else
+           strings_processed = 2, add_path (argv[i + 1], BRACKET, false);
+       }
+      else
+       strings_processed = cpp_handle_option (scan_in, argc - i, argv + i);
+
+      if (strings_processed == 0)
+       break;
+    }
+
   if (i < argc)
     cpp_error (scan_in, DL_ERROR, "invalid option `%s'", argv[i]);
   if (cpp_errors (scan_in))
     exit (FATAL_EXIT_CODE);
 
+  register_include_chains (scan_in, NULL /* sysroot */, NULL /* iprefix */,
+                          true /* stdinc */, false /* cxx_stdinc */,
+                          false /* verbose */);
   if (! cpp_read_main_file (scan_in, in_fname, NULL))
     exit (FATAL_EXIT_CODE);