1 /* Set up combined include path chain for the preprocessor.
\r
2 Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
\r
3 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
\r
5 Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003.
\r
7 This program is free software; you can redistribute it and/or modify it
\r
8 under the terms of the GNU General Public License as published by the
\r
9 Free Software Foundation; either version 2, or (at your option) any
\r
12 This program is distributed in the hope that it will be useful,
\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
15 GNU General Public License for more details.
\r
17 You should have received a copy of the GNU General Public License
\r
18 along with this program; if not, write to the Free Software
\r
19 Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
\r
26 #include "c-incpath.h"
\r
27 #include "cppdefault.h"
\r
29 /* Windows does not natively support inodes, and neither does MSDOS.
\r
30 Cygwin's emulation can generate non-unique inodes, so don't use it.
\r
31 VMS has non-numeric inodes. */
\r
33 # define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
\r
34 # define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
\r
36 # if (defined _WIN32 && !defined (_UWIN)) || defined __MSDOS__
\r
37 # define INO_T_EQ(A, B) 0
\r
39 # define INO_T_EQ(A, B) ((A) == (B))
\r
41 # define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
\r
44 static void add_env_var_paths (const char *, int);
\r
45 static void add_standard_paths (const char *, const char *, int);
\r
46 static void free_path (struct cpp_dir *, int);
\r
47 static void merge_include_chains (cpp_reader *, int);
\r
48 static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *,
\r
50 struct cpp_dir *, int);
\r
52 /* Include chains heads and tails. */
\r
53 static struct cpp_dir *heads[4];
\r
54 static struct cpp_dir *tails[4];
\r
55 static bool quote_ignores_source_dir;
\r
56 enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS };
\r
58 /* Free an element of the include chain, possibly giving a reason. */
\r
60 free_path (struct cpp_dir *path, int reason)
\r
65 case REASON_DUP_SYS:
\r
66 fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), path->name);
\r
67 if (reason == REASON_DUP_SYS)
\r
69 _(" as it is a non-system directory that duplicates a system directory\n"));
\r
73 fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"),
\r
86 /* Read ENV_VAR for a PATH_SEPARATOR-separated list of file names; and
\r
87 append all the names to the search path CHAIN. */
\r
89 add_env_var_paths (const char *env_var, int chain)
\r
93 GET_ENVIRONMENT (q, env_var);
\r
98 for (p = q; *q; p = q + 1)
\r
101 while (*q != 0 && *q != PATH_SEPARATOR)
\r
105 path = xstrdup (".");
\r
108 path = xmalloc (q - p + 1);
\r
109 memcpy (path, p, q - p);
\r
110 path[q - p] = '\0';
\r
113 add_path (path, chain, chain == SYSTEM, false);
\r
117 /* Append the standard include chain defined in cppdefault.c. */
\r
119 add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
\r
121 const struct default_include *p;
\r
124 if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0)
\r
126 /* Look for directories that start with the standard prefix.
\r
127 "Translate" them, i.e. replace /usr/local/lib/gcc... with
\r
128 IPREFIX and search them first. */
\r
129 for (p = cpp_include_defaults; p->fname; p++)
\r
131 if (!p->cplusplus || cxx_stdinc)
\r
133 /* Should we be translating sysrooted dirs too? Assume
\r
134 that iprefix and sysroot are mutually exclusive, for
\r
136 if (sysroot && p->add_sysroot)
\r
138 if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
\r
140 char *str = concat (iprefix, p->fname + len, NULL);
\r
141 add_path (str, SYSTEM, p->cxx_aware, false);
\r
147 for (p = cpp_include_defaults; p->fname; p++)
\r
149 if (!p->cplusplus || cxx_stdinc)
\r
153 /* Should this directory start with the sysroot? */
\r
154 if (sysroot && p->add_sysroot)
\r
155 str = concat (sysroot, p->fname, NULL);
\r
157 str = update_path (p->fname, p->component);
\r
159 add_path (str, SYSTEM, p->cxx_aware, false);
\r
164 /* For each duplicate path in chain HEAD, keep just the first one.
\r
165 Remove each path in chain HEAD that also exists in chain SYSTEM.
\r
166 Set the NEXT pointer of the last path in the resulting chain to
\r
167 JOIN, unless it duplicates JOIN in which case the last path is
\r
168 removed. Return the head of the resulting chain. Any of HEAD,
\r
169 JOIN and SYSTEM can be NULL. */
\r
171 static struct cpp_dir *
\r
172 remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
\r
173 struct cpp_dir *system, struct cpp_dir *join,
\r
176 struct cpp_dir **pcur, *tmp, *cur;
\r
179 for (pcur = &head; *pcur; )
\r
181 int reason = REASON_QUIET;
\r
185 if (stat (cur->name, &st))
\r
187 /* Dirs that don't exist are silently ignored, unless verbose. */
\r
188 if (errno != ENOENT)
\r
189 cpp_errno (pfile, CPP_DL_ERROR, cur->name);
\r
192 /* If -Wmissing-include-dirs is given, warn. */
\r
193 cpp_options *opts = cpp_get_options (pfile);
\r
194 if (opts->warn_missing_include_dirs && cur->user_supplied_p)
\r
195 cpp_errno (pfile, CPP_DL_WARNING, cur->name);
\r
196 reason = REASON_NOENT;
\r
199 else if (!S_ISDIR (st.st_mode))
\r
200 cpp_error_with_line (pfile, CPP_DL_ERROR, 0, 0,
\r
201 "%s: not a directory", cur->name);
\r
204 INO_T_COPY (cur->ino, st.st_ino);
\r
205 cur->dev = st.st_dev;
\r
207 /* Remove this one if it is in the system chain. */
\r
208 reason = REASON_DUP_SYS;
\r
209 for (tmp = system; tmp; tmp = tmp->next)
\r
210 if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev
\r
211 && cur->construct == tmp->construct)
\r
216 /* Duplicate of something earlier in the same chain? */
\r
217 reason = REASON_DUP;
\r
218 for (tmp = head; tmp != cur; tmp = tmp->next)
\r
219 if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev
\r
220 && cur->construct == tmp->construct)
\r
224 /* Last in the chain and duplicate of JOIN? */
\r
225 && !(cur->next == NULL && join
\r
226 && INO_T_EQ (cur->ino, join->ino)
\r
227 && cur->dev == join->dev
\r
228 && cur->construct == join->construct))
\r
230 /* Unique, so keep this directory. */
\r
237 /* Remove this entry from the chain. */
\r
239 free_path (cur, verbose ? reason: REASON_QUIET);
\r
246 /* Merge the four include chains together in the order quote, bracket,
\r
247 system, after. Remove duplicate dirs (as determined by
\r
250 We can't just merge the lists and then uniquify them because then
\r
251 we may lose directories from the <> search path that should be
\r
252 there; consider -iquote foo -iquote bar -Ifoo -Iquux. It is
\r
253 however safe to treat -iquote bar -iquote foo -Ifoo -Iquux as if
\r
254 written -iquote bar -Ifoo -Iquux. */
\r
257 merge_include_chains (cpp_reader *pfile, int verbose)
\r
259 /* Join the SYSTEM and AFTER chains. Remove duplicates in the
\r
260 resulting SYSTEM chain. */
\r
262 tails[SYSTEM]->next = heads[AFTER];
\r
264 heads[SYSTEM] = heads[AFTER];
\r
265 heads[SYSTEM] = remove_duplicates (pfile, heads[SYSTEM], 0, 0, verbose);
\r
267 /* Remove duplicates from BRACKET that are in itself or SYSTEM, and
\r
268 join it to SYSTEM. */
\r
269 heads[BRACKET] = remove_duplicates (pfile, heads[BRACKET], heads[SYSTEM],
\r
270 heads[SYSTEM], verbose);
\r
272 /* Remove duplicates from QUOTE that are in itself or SYSTEM, and
\r
273 join it to BRACKET. */
\r
274 heads[QUOTE] = remove_duplicates (pfile, heads[QUOTE], heads[SYSTEM],
\r
275 heads[BRACKET], verbose);
\r
277 /* If verbose, print the list of dirs to search. */
\r
282 fprintf (stderr, _("#include \"...\" search starts here:\n"));
\r
283 for (p = heads[QUOTE];; p = p->next)
\r
285 if (p == heads[BRACKET])
\r
286 fprintf (stderr, _("#include <...> search starts here:\n"));
\r
289 fprintf (stderr, " %s\n", p->name);
\r
291 fprintf (stderr, _("End of search list.\n"));
\r
295 /* Use given -I paths for #include "..." but not #include <...>, and
\r
296 don't search the directory of the present file for #include "...".
\r
297 (Note that -I. -I- is not the same as the default setup; -I. uses
\r
298 the compiler's working dir.) */
\r
300 split_quote_chain (void)
\r
302 heads[QUOTE] = heads[BRACKET];
\r
303 tails[QUOTE] = tails[BRACKET];
\r
304 heads[BRACKET] = NULL;
\r
305 tails[BRACKET] = NULL;
\r
306 /* This is NOT redundant. */
\r
307 quote_ignores_source_dir = true;
\r
310 /* Add P to the chain specified by CHAIN. */
\r
313 add_cpp_dir_path (cpp_dir *p, int chain)
\r
316 tails[chain]->next = p;
\r
322 /* Add PATH to the include chain CHAIN. PATH must be malloc-ed and
\r
325 add_path (char *path, int chain, int cxx_aware, bool user_supplied_p)
\r
329 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
\r
330 /* Convert all backslashes to slashes. The native CRT stat()
\r
331 function does not recognize a directory that ends in a backslash
\r
332 (unless it is a drive root dir, such "c:\"). Forward slashes,
\r
333 trailing or otherwise, cause no problems for stat(). */
\r
335 for (c = path; *c; c++)
\r
336 if (*c == '\\') *c = '/';
\r
339 p = xmalloc (sizeof (cpp_dir));
\r
342 if (chain == SYSTEM || chain == AFTER)
\r
343 p->sysp = 1 + !cxx_aware;
\r
347 p->user_supplied_p = user_supplied_p;
\r
349 add_cpp_dir_path (p, chain);
\r
352 /* Exported function to handle include chain merging, duplicate
\r
353 removal, and registration with cpplib. */
\r
355 register_include_chains (cpp_reader *pfile, const char *sysroot,
\r
356 const char *iprefix, int stdinc, int cxx_stdinc,
\r
359 static const char *const lang_env_vars[] =
\r
360 { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
\r
361 "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
\r
362 cpp_options *cpp_opts = cpp_get_options (pfile);
\r
363 size_t idx = (cpp_opts->objc ? 2: 0);
\r
365 if (cpp_opts->cplusplus)
\r
368 cxx_stdinc = false;
\r
370 /* CPATH and language-dependent environment variables may add to the
\r
372 add_env_var_paths ("CPATH", BRACKET);
\r
373 add_env_var_paths (lang_env_vars[idx], SYSTEM);
\r
375 target_c_incpath.extra_pre_includes (sysroot, iprefix, stdinc);
\r
377 /* Finally chain on the standard directories. */
\r
379 add_standard_paths (sysroot, iprefix, cxx_stdinc);
\r
381 target_c_incpath.extra_includes (sysroot, iprefix, stdinc);
\r
383 merge_include_chains (pfile, verbose);
\r
385 cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET],
\r
386 quote_ignores_source_dir);
\r
388 #if !(defined TARGET_EXTRA_INCLUDES) || !(defined TARGET_EXTRA_PRE_INCLUDES)
\r
389 static void hook_void_charptr_charptr_int (const char *sysroot ATTRIBUTE_UNUSED,
\r
390 const char *iprefix ATTRIBUTE_UNUSED,
\r
391 int stdinc ATTRIBUTE_UNUSED)
\r
396 #ifndef TARGET_EXTRA_INCLUDES
\r
397 #define TARGET_EXTRA_INCLUDES hook_void_charptr_charptr_int
\r
399 #ifndef TARGET_EXTRA_PRE_INCLUDES
\r
400 #define TARGET_EXTRA_PRE_INCLUDES hook_void_charptr_charptr_int
\r
403 struct target_c_incpath_s target_c_incpath = { TARGET_EXTRA_PRE_INCLUDES, TARGET_EXTRA_INCLUDES };
\r