summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog44
-rw-r--r--gcc/Makefile.in20
-rw-r--r--gcc/c-incpath.c510
-rw-r--r--gcc/c-incpath.h24
-rw-r--r--gcc/c-lex.c4
-rw-r--r--gcc/c-opts.c106
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/Make-lang.in3
-rw-r--r--gcc/cppdefault.c21
-rw-r--r--gcc/cppdefault.h28
-rw-r--r--gcc/cppfiles.c224
-rw-r--r--gcc/cpphash.h33
-rw-r--r--gcc/cppinit.c530
-rw-r--r--gcc/cpplib.h63
-rw-r--r--gcc/doc/passes.texi2
-rw-r--r--gcc/fix-header.c28
16 files changed, 841 insertions, 803 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 90086bdf9ca..ed7f0ef3ea4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 9510321e339..22c1fe5d25d 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -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
index 00000000000..96bf69d7e28
--- /dev/null
+++ b/gcc/c-incpath.c
@@ -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
index 00000000000..860ea3cdc95
--- /dev/null
+++ b/gcc/c-incpath.h
@@ -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 };
diff --git a/gcc/c-lex.c b/gcc/c-lex.c
index ab068207e1d..e0617bd142d 100644
--- a/gcc/c-lex.c
+++ b/gcc/c-lex.c
@@ -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;
diff --git a/gcc/c-opts.c b/gcc/c-opts.c
index 075112e31f9..c5f25c99384 100644
--- a/gcc/c-opts.c
+++ b/gcc/c-opts.c
@@ -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\
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1fc78b045d8..c5db4812b01 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 7d8804cfbf6..da874b900e4 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -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 \
diff --git a/gcc/cppdefault.c b/gcc/cppdefault.c
index da4ddb5411c..cc96da7f6db 100644
--- a/gcc/cppdefault.c
+++ b/gcc/cppdefault.c
@@ -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;
diff --git a/gcc/cppdefault.h b/gcc/cppdefault.h
index c87e27d5dee..368e082c79d 100644
--- a/gcc/cppdefault.h
+++ b/gcc/cppdefault.h
@@ -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. */
};
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index 1f5d6c3de51..502e8a2e161 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -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 */
}
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index 9aff511678c..16aba087b88 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -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 *,
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 40b5059612e..2068ba1d675 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -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;
diff --git a/gcc/cpplib.h b/gcc/cpplib.h
index 322562731af..384dd209ac2 100644
--- a/gcc/cpplib.h
+++ b/gcc/cpplib.h
@@ -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
diff --git a/gcc/doc/passes.texi b/gcc/doc/passes.texi
index 10cc3815c98..107fe5d2437 100644
--- a/gcc/doc/passes.texi
+++ b/gcc/doc/passes.texi
@@ -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},
diff --git a/gcc/fix-header.c b/gcc/fix-header.c
index d722450a622..305a8685222 100644
--- a/gcc/fix-header.c
+++ b/gcc/fix-header.c
@@ -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);