diff options
-rw-r--r-- | gcc/ChangeLog | 44 | ||||
-rw-r--r-- | gcc/Makefile.in | 20 | ||||
-rw-r--r-- | gcc/c-incpath.c | 510 | ||||
-rw-r--r-- | gcc/c-incpath.h | 24 | ||||
-rw-r--r-- | gcc/c-lex.c | 4 | ||||
-rw-r--r-- | gcc/c-opts.c | 106 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/Make-lang.in | 3 | ||||
-rw-r--r-- | gcc/cppdefault.c | 21 | ||||
-rw-r--r-- | gcc/cppdefault.h | 28 | ||||
-rw-r--r-- | gcc/cppfiles.c | 224 | ||||
-rw-r--r-- | gcc/cpphash.h | 33 | ||||
-rw-r--r-- | gcc/cppinit.c | 530 | ||||
-rw-r--r-- | gcc/cpplib.h | 63 | ||||
-rw-r--r-- | gcc/doc/passes.texi | 2 | ||||
-rw-r--r-- | gcc/fix-header.c | 28 |
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, "e); - qtail->next = brack; - - qtail = remove_dup_nonsys_dirs (pfile, "e, 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, "e); - } - 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); |