1*38fd1498Szrj /* Set up combined include path chain for the preprocessor.
2*38fd1498Szrj Copyright (C) 1986-2018 Free Software Foundation, Inc.
3*38fd1498Szrj
4*38fd1498Szrj Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003.
5*38fd1498Szrj
6*38fd1498Szrj This program is free software; you can redistribute it and/or modify it
7*38fd1498Szrj under the terms of the GNU General Public License as published by the
8*38fd1498Szrj Free Software Foundation; either version 3, or (at your option) any
9*38fd1498Szrj later version.
10*38fd1498Szrj
11*38fd1498Szrj This program is distributed in the hope that it will be useful,
12*38fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*38fd1498Szrj GNU General Public License for more details.
15*38fd1498Szrj
16*38fd1498Szrj You should have received a copy of the GNU General Public License
17*38fd1498Szrj along with this program; see the file COPYING3. If not see
18*38fd1498Szrj <http://www.gnu.org/licenses/>. */
19*38fd1498Szrj
20*38fd1498Szrj #include "config.h"
21*38fd1498Szrj #include "system.h"
22*38fd1498Szrj #include "coretypes.h"
23*38fd1498Szrj #include "target.h"
24*38fd1498Szrj #include "cpplib.h"
25*38fd1498Szrj #include "prefix.h"
26*38fd1498Szrj #include "intl.h"
27*38fd1498Szrj #include "incpath.h"
28*38fd1498Szrj #include "cppdefault.h"
29*38fd1498Szrj
30*38fd1498Szrj /* Microsoft Windows does not natively support inodes.
31*38fd1498Szrj VMS has non-numeric inodes. */
32*38fd1498Szrj #ifdef VMS
33*38fd1498Szrj # define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
34*38fd1498Szrj # define INO_T_COPY(DEST, SRC) memcpy (&(DEST), &(SRC), sizeof (SRC))
35*38fd1498Szrj #elif !defined (HOST_LACKS_INODE_NUMBERS)
36*38fd1498Szrj # define INO_T_EQ(A, B) ((A) == (B))
37*38fd1498Szrj # define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
38*38fd1498Szrj #endif
39*38fd1498Szrj
40*38fd1498Szrj #if defined INO_T_EQ
41*38fd1498Szrj #define DIRS_EQ(A, B) ((A)->dev == (B)->dev \
42*38fd1498Szrj && INO_T_EQ ((A)->ino, (B)->ino))
43*38fd1498Szrj #else
44*38fd1498Szrj #define DIRS_EQ(A, B) (!filename_cmp ((A)->canonical_name, (B)->canonical_name))
45*38fd1498Szrj #endif
46*38fd1498Szrj
47*38fd1498Szrj static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
48*38fd1498Szrj
49*38fd1498Szrj static void add_env_var_paths (const char *, incpath_kind);
50*38fd1498Szrj static void add_standard_paths (const char *, const char *, const char *, int);
51*38fd1498Szrj static void free_path (struct cpp_dir *, int);
52*38fd1498Szrj static void merge_include_chains (const char *, cpp_reader *, int);
53*38fd1498Szrj static void add_sysroot_to_chain (const char *, int);
54*38fd1498Szrj static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *,
55*38fd1498Szrj struct cpp_dir *,
56*38fd1498Szrj struct cpp_dir *, int);
57*38fd1498Szrj
58*38fd1498Szrj /* Include chains heads and tails. */
59*38fd1498Szrj static struct cpp_dir *heads[INC_MAX];
60*38fd1498Szrj static struct cpp_dir *tails[INC_MAX];
61*38fd1498Szrj
62*38fd1498Szrj static bool quote_ignores_source_dir;
63*38fd1498Szrj enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS };
64*38fd1498Szrj
65*38fd1498Szrj /* Free an element of the include chain, possibly giving a reason. */
66*38fd1498Szrj static void
free_path(struct cpp_dir * path,int reason)67*38fd1498Szrj free_path (struct cpp_dir *path, int reason)
68*38fd1498Szrj {
69*38fd1498Szrj switch (reason)
70*38fd1498Szrj {
71*38fd1498Szrj case REASON_DUP:
72*38fd1498Szrj case REASON_DUP_SYS:
73*38fd1498Szrj fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), path->name);
74*38fd1498Szrj if (reason == REASON_DUP_SYS)
75*38fd1498Szrj fprintf (stderr,
76*38fd1498Szrj _(" as it is a non-system directory that duplicates a system directory\n"));
77*38fd1498Szrj break;
78*38fd1498Szrj
79*38fd1498Szrj case REASON_NOENT:
80*38fd1498Szrj fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"),
81*38fd1498Szrj path->name);
82*38fd1498Szrj break;
83*38fd1498Szrj
84*38fd1498Szrj case REASON_QUIET:
85*38fd1498Szrj default:
86*38fd1498Szrj break;
87*38fd1498Szrj }
88*38fd1498Szrj
89*38fd1498Szrj free (path->name);
90*38fd1498Szrj free (path);
91*38fd1498Szrj }
92*38fd1498Szrj
93*38fd1498Szrj /* Read ENV_VAR for a PATH_SEPARATOR-separated list of file names; and
94*38fd1498Szrj append all the names to the search path CHAIN. */
95*38fd1498Szrj static void
add_env_var_paths(const char * env_var,incpath_kind chain)96*38fd1498Szrj add_env_var_paths (const char *env_var, incpath_kind chain)
97*38fd1498Szrj {
98*38fd1498Szrj char *p, *q, *path;
99*38fd1498Szrj
100*38fd1498Szrj q = getenv (env_var);
101*38fd1498Szrj
102*38fd1498Szrj if (!q)
103*38fd1498Szrj return;
104*38fd1498Szrj
105*38fd1498Szrj for (p = q; *q; p = q + 1)
106*38fd1498Szrj {
107*38fd1498Szrj q = p;
108*38fd1498Szrj while (*q != 0 && *q != PATH_SEPARATOR)
109*38fd1498Szrj q++;
110*38fd1498Szrj
111*38fd1498Szrj if (p == q)
112*38fd1498Szrj path = xstrdup (".");
113*38fd1498Szrj else
114*38fd1498Szrj {
115*38fd1498Szrj path = XNEWVEC (char, q - p + 1);
116*38fd1498Szrj memcpy (path, p, q - p);
117*38fd1498Szrj path[q - p] = '\0';
118*38fd1498Szrj }
119*38fd1498Szrj
120*38fd1498Szrj add_path (path, chain, chain == INC_SYSTEM, false);
121*38fd1498Szrj }
122*38fd1498Szrj }
123*38fd1498Szrj
124*38fd1498Szrj /* Append the standard include chain defined in cppdefault.c. */
125*38fd1498Szrj static void
add_standard_paths(const char * sysroot,const char * iprefix,const char * imultilib,int cxx_stdinc)126*38fd1498Szrj add_standard_paths (const char *sysroot, const char *iprefix,
127*38fd1498Szrj const char *imultilib, int cxx_stdinc)
128*38fd1498Szrj {
129*38fd1498Szrj const struct default_include *p;
130*38fd1498Szrj int relocated = cpp_relocated ();
131*38fd1498Szrj size_t len;
132*38fd1498Szrj
133*38fd1498Szrj if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0)
134*38fd1498Szrj {
135*38fd1498Szrj /* Look for directories that start with the standard prefix.
136*38fd1498Szrj "Translate" them, i.e. replace /usr/local/lib/gcc... with
137*38fd1498Szrj IPREFIX and search them first. */
138*38fd1498Szrj for (p = cpp_include_defaults; p->fname; p++)
139*38fd1498Szrj {
140*38fd1498Szrj if (!p->cplusplus || cxx_stdinc)
141*38fd1498Szrj {
142*38fd1498Szrj /* Should we be translating sysrooted dirs too? Assume
143*38fd1498Szrj that iprefix and sysroot are mutually exclusive, for
144*38fd1498Szrj now. */
145*38fd1498Szrj if (sysroot && p->add_sysroot)
146*38fd1498Szrj continue;
147*38fd1498Szrj if (!filename_ncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
148*38fd1498Szrj {
149*38fd1498Szrj char *str = concat (iprefix, p->fname + len, NULL);
150*38fd1498Szrj if (p->multilib == 1 && imultilib)
151*38fd1498Szrj str = reconcat (str, str, dir_separator_str,
152*38fd1498Szrj imultilib, NULL);
153*38fd1498Szrj else if (p->multilib == 2)
154*38fd1498Szrj {
155*38fd1498Szrj if (!imultiarch)
156*38fd1498Szrj {
157*38fd1498Szrj free (str);
158*38fd1498Szrj continue;
159*38fd1498Szrj }
160*38fd1498Szrj str = reconcat (str, str, dir_separator_str,
161*38fd1498Szrj imultiarch, NULL);
162*38fd1498Szrj }
163*38fd1498Szrj add_path (str, INC_SYSTEM, p->cxx_aware, false);
164*38fd1498Szrj }
165*38fd1498Szrj }
166*38fd1498Szrj }
167*38fd1498Szrj }
168*38fd1498Szrj
169*38fd1498Szrj for (p = cpp_include_defaults; p->fname; p++)
170*38fd1498Szrj {
171*38fd1498Szrj if (!p->cplusplus || cxx_stdinc)
172*38fd1498Szrj {
173*38fd1498Szrj char *str;
174*38fd1498Szrj
175*38fd1498Szrj /* Should this directory start with the sysroot? */
176*38fd1498Szrj if (sysroot && p->add_sysroot)
177*38fd1498Szrj {
178*38fd1498Szrj char *sysroot_no_trailing_dir_separator = xstrdup (sysroot);
179*38fd1498Szrj size_t sysroot_len = strlen (sysroot);
180*38fd1498Szrj
181*38fd1498Szrj if (sysroot_len > 0 && sysroot[sysroot_len - 1] == DIR_SEPARATOR)
182*38fd1498Szrj sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
183*38fd1498Szrj str = concat (sysroot_no_trailing_dir_separator, p->fname, NULL);
184*38fd1498Szrj free (sysroot_no_trailing_dir_separator);
185*38fd1498Szrj }
186*38fd1498Szrj else if (!p->add_sysroot && relocated
187*38fd1498Szrj && !filename_ncmp (p->fname, cpp_PREFIX, cpp_PREFIX_len))
188*38fd1498Szrj {
189*38fd1498Szrj static const char *relocated_prefix;
190*38fd1498Szrj char *ostr;
191*38fd1498Szrj /* If this path starts with the configure-time prefix,
192*38fd1498Szrj but the compiler has been relocated, replace it
193*38fd1498Szrj with the run-time prefix. The run-time exec prefix
194*38fd1498Szrj is GCC_EXEC_PREFIX. Compute the path from there back
195*38fd1498Szrj to the toplevel prefix. */
196*38fd1498Szrj if (!relocated_prefix)
197*38fd1498Szrj {
198*38fd1498Szrj char *dummy;
199*38fd1498Szrj /* Make relative prefix expects the first argument
200*38fd1498Szrj to be a program, not a directory. */
201*38fd1498Szrj dummy = concat (gcc_exec_prefix, "dummy", NULL);
202*38fd1498Szrj relocated_prefix
203*38fd1498Szrj = make_relative_prefix (dummy,
204*38fd1498Szrj cpp_EXEC_PREFIX,
205*38fd1498Szrj cpp_PREFIX);
206*38fd1498Szrj free (dummy);
207*38fd1498Szrj }
208*38fd1498Szrj ostr = concat (relocated_prefix,
209*38fd1498Szrj p->fname + cpp_PREFIX_len,
210*38fd1498Szrj NULL);
211*38fd1498Szrj str = update_path (ostr, p->component);
212*38fd1498Szrj free (ostr);
213*38fd1498Szrj }
214*38fd1498Szrj else
215*38fd1498Szrj str = update_path (p->fname, p->component);
216*38fd1498Szrj
217*38fd1498Szrj if (p->multilib == 1 && imultilib)
218*38fd1498Szrj str = reconcat (str, str, dir_separator_str, imultilib, NULL);
219*38fd1498Szrj else if (p->multilib == 2)
220*38fd1498Szrj {
221*38fd1498Szrj if (!imultiarch)
222*38fd1498Szrj {
223*38fd1498Szrj free (str);
224*38fd1498Szrj continue;
225*38fd1498Szrj }
226*38fd1498Szrj str = reconcat (str, str, dir_separator_str, imultiarch, NULL);
227*38fd1498Szrj }
228*38fd1498Szrj
229*38fd1498Szrj add_path (str, INC_SYSTEM, p->cxx_aware, false);
230*38fd1498Szrj }
231*38fd1498Szrj }
232*38fd1498Szrj }
233*38fd1498Szrj
234*38fd1498Szrj /* For each duplicate path in chain HEAD, keep just the first one.
235*38fd1498Szrj Remove each path in chain HEAD that also exists in chain SYSTEM.
236*38fd1498Szrj Set the NEXT pointer of the last path in the resulting chain to
237*38fd1498Szrj JOIN, unless it duplicates JOIN in which case the last path is
238*38fd1498Szrj removed. Return the head of the resulting chain. Any of HEAD,
239*38fd1498Szrj JOIN and SYSTEM can be NULL. */
240*38fd1498Szrj
241*38fd1498Szrj static struct cpp_dir *
remove_duplicates(cpp_reader * pfile,struct cpp_dir * head,struct cpp_dir * system,struct cpp_dir * join,int verbose)242*38fd1498Szrj remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
243*38fd1498Szrj struct cpp_dir *system, struct cpp_dir *join,
244*38fd1498Szrj int verbose)
245*38fd1498Szrj {
246*38fd1498Szrj struct cpp_dir **pcur, *tmp, *cur;
247*38fd1498Szrj struct stat st;
248*38fd1498Szrj
249*38fd1498Szrj for (pcur = &head; *pcur; )
250*38fd1498Szrj {
251*38fd1498Szrj int reason = REASON_QUIET;
252*38fd1498Szrj
253*38fd1498Szrj cur = *pcur;
254*38fd1498Szrj
255*38fd1498Szrj if (stat (cur->name, &st))
256*38fd1498Szrj {
257*38fd1498Szrj /* Dirs that don't exist or have denied permissions are
258*38fd1498Szrj silently ignored, unless verbose. */
259*38fd1498Szrj if ((errno != ENOENT) && (errno != EPERM))
260*38fd1498Szrj cpp_errno (pfile, CPP_DL_ERROR, cur->name);
261*38fd1498Szrj else
262*38fd1498Szrj {
263*38fd1498Szrj /* If -Wmissing-include-dirs is given, warn. */
264*38fd1498Szrj cpp_options *opts = cpp_get_options (pfile);
265*38fd1498Szrj if (opts->warn_missing_include_dirs && cur->user_supplied_p)
266*38fd1498Szrj cpp_warning (pfile, CPP_W_MISSING_INCLUDE_DIRS, "%s: %s",
267*38fd1498Szrj cur->name, xstrerror (errno));
268*38fd1498Szrj reason = REASON_NOENT;
269*38fd1498Szrj }
270*38fd1498Szrj }
271*38fd1498Szrj else if (!S_ISDIR (st.st_mode))
272*38fd1498Szrj cpp_error_with_line (pfile, CPP_DL_WARNING, 0, 0,
273*38fd1498Szrj "%s: not a directory", cur->name);
274*38fd1498Szrj else
275*38fd1498Szrj {
276*38fd1498Szrj #if defined (INO_T_COPY)
277*38fd1498Szrj INO_T_COPY (cur->ino, st.st_ino);
278*38fd1498Szrj cur->dev = st.st_dev;
279*38fd1498Szrj #endif
280*38fd1498Szrj
281*38fd1498Szrj /* Remove this one if it is in the system chain. */
282*38fd1498Szrj reason = REASON_DUP_SYS;
283*38fd1498Szrj for (tmp = system; tmp; tmp = tmp->next)
284*38fd1498Szrj if (DIRS_EQ (tmp, cur) && cur->construct == tmp->construct)
285*38fd1498Szrj break;
286*38fd1498Szrj
287*38fd1498Szrj if (!tmp)
288*38fd1498Szrj {
289*38fd1498Szrj /* Duplicate of something earlier in the same chain? */
290*38fd1498Szrj reason = REASON_DUP;
291*38fd1498Szrj for (tmp = head; tmp != cur; tmp = tmp->next)
292*38fd1498Szrj if (DIRS_EQ (cur, tmp) && cur->construct == tmp->construct)
293*38fd1498Szrj break;
294*38fd1498Szrj
295*38fd1498Szrj if (tmp == cur
296*38fd1498Szrj /* Last in the chain and duplicate of JOIN? */
297*38fd1498Szrj && !(cur->next == NULL && join
298*38fd1498Szrj && DIRS_EQ (cur, join)
299*38fd1498Szrj && cur->construct == join->construct))
300*38fd1498Szrj {
301*38fd1498Szrj /* Unique, so keep this directory. */
302*38fd1498Szrj pcur = &cur->next;
303*38fd1498Szrj continue;
304*38fd1498Szrj }
305*38fd1498Szrj }
306*38fd1498Szrj }
307*38fd1498Szrj
308*38fd1498Szrj /* Remove this entry from the chain. */
309*38fd1498Szrj *pcur = cur->next;
310*38fd1498Szrj free_path (cur, verbose ? reason: REASON_QUIET);
311*38fd1498Szrj }
312*38fd1498Szrj
313*38fd1498Szrj *pcur = join;
314*38fd1498Szrj return head;
315*38fd1498Szrj }
316*38fd1498Szrj
317*38fd1498Szrj /* Add SYSROOT to any user-supplied paths in CHAIN starting with
318*38fd1498Szrj "=" or "$SYSROOT". */
319*38fd1498Szrj
320*38fd1498Szrj static void
add_sysroot_to_chain(const char * sysroot,int chain)321*38fd1498Szrj add_sysroot_to_chain (const char *sysroot, int chain)
322*38fd1498Szrj {
323*38fd1498Szrj struct cpp_dir *p;
324*38fd1498Szrj
325*38fd1498Szrj for (p = heads[chain]; p != NULL; p = p->next)
326*38fd1498Szrj {
327*38fd1498Szrj if (p->user_supplied_p)
328*38fd1498Szrj {
329*38fd1498Szrj if (p->name[0] == '=')
330*38fd1498Szrj p->name = concat (sysroot, p->name + 1, NULL);
331*38fd1498Szrj if (strncmp (p->name, "$SYSROOT", strlen ("$SYSROOT")) == 0)
332*38fd1498Szrj p->name = concat (sysroot, p->name + strlen ("$SYSROOT"), NULL);
333*38fd1498Szrj }
334*38fd1498Szrj }
335*38fd1498Szrj }
336*38fd1498Szrj
337*38fd1498Szrj /* Merge the four include chains together in the order quote, bracket,
338*38fd1498Szrj system, after. Remove duplicate dirs (determined in
339*38fd1498Szrj system-specific manner).
340*38fd1498Szrj
341*38fd1498Szrj We can't just merge the lists and then uniquify them because then
342*38fd1498Szrj we may lose directories from the <> search path that should be
343*38fd1498Szrj there; consider -iquote foo -iquote bar -Ifoo -Iquux. It is
344*38fd1498Szrj however safe to treat -iquote bar -iquote foo -Ifoo -Iquux as if
345*38fd1498Szrj written -iquote bar -Ifoo -Iquux. */
346*38fd1498Szrj
347*38fd1498Szrj static void
merge_include_chains(const char * sysroot,cpp_reader * pfile,int verbose)348*38fd1498Szrj merge_include_chains (const char *sysroot, cpp_reader *pfile, int verbose)
349*38fd1498Szrj {
350*38fd1498Szrj /* Add the sysroot to user-supplied paths starting with "=". */
351*38fd1498Szrj if (sysroot)
352*38fd1498Szrj {
353*38fd1498Szrj add_sysroot_to_chain (sysroot, INC_QUOTE);
354*38fd1498Szrj add_sysroot_to_chain (sysroot, INC_BRACKET);
355*38fd1498Szrj add_sysroot_to_chain (sysroot, INC_SYSTEM);
356*38fd1498Szrj add_sysroot_to_chain (sysroot, INC_AFTER);
357*38fd1498Szrj }
358*38fd1498Szrj
359*38fd1498Szrj /* Join the SYSTEM and AFTER chains. Remove duplicates in the
360*38fd1498Szrj resulting SYSTEM chain. */
361*38fd1498Szrj if (heads[INC_SYSTEM])
362*38fd1498Szrj tails[INC_SYSTEM]->next = heads[INC_AFTER];
363*38fd1498Szrj else
364*38fd1498Szrj heads[INC_SYSTEM] = heads[INC_AFTER];
365*38fd1498Szrj heads[INC_SYSTEM]
366*38fd1498Szrj = remove_duplicates (pfile, heads[INC_SYSTEM], 0, 0, verbose);
367*38fd1498Szrj
368*38fd1498Szrj /* Remove duplicates from BRACKET that are in itself or SYSTEM, and
369*38fd1498Szrj join it to SYSTEM. */
370*38fd1498Szrj heads[INC_BRACKET]
371*38fd1498Szrj = remove_duplicates (pfile, heads[INC_BRACKET], heads[INC_SYSTEM],
372*38fd1498Szrj heads[INC_SYSTEM], verbose);
373*38fd1498Szrj
374*38fd1498Szrj /* Remove duplicates from QUOTE that are in itself or SYSTEM, and
375*38fd1498Szrj join it to BRACKET. */
376*38fd1498Szrj heads[INC_QUOTE]
377*38fd1498Szrj = remove_duplicates (pfile, heads[INC_QUOTE], heads[INC_SYSTEM],
378*38fd1498Szrj heads[INC_BRACKET], verbose);
379*38fd1498Szrj
380*38fd1498Szrj /* If verbose, print the list of dirs to search. */
381*38fd1498Szrj if (verbose)
382*38fd1498Szrj {
383*38fd1498Szrj struct cpp_dir *p;
384*38fd1498Szrj
385*38fd1498Szrj fprintf (stderr, _("#include \"...\" search starts here:\n"));
386*38fd1498Szrj for (p = heads[INC_QUOTE];; p = p->next)
387*38fd1498Szrj {
388*38fd1498Szrj if (p == heads[INC_BRACKET])
389*38fd1498Szrj fprintf (stderr, _("#include <...> search starts here:\n"));
390*38fd1498Szrj if (!p)
391*38fd1498Szrj break;
392*38fd1498Szrj fprintf (stderr, " %s\n", p->name);
393*38fd1498Szrj }
394*38fd1498Szrj fprintf (stderr, _("End of search list.\n"));
395*38fd1498Szrj }
396*38fd1498Szrj }
397*38fd1498Szrj
398*38fd1498Szrj /* Use given -I paths for #include "..." but not #include <...>, and
399*38fd1498Szrj don't search the directory of the present file for #include "...".
400*38fd1498Szrj (Note that -I. -I- is not the same as the default setup; -I. uses
401*38fd1498Szrj the compiler's working dir.) */
402*38fd1498Szrj void
split_quote_chain(void)403*38fd1498Szrj split_quote_chain (void)
404*38fd1498Szrj {
405*38fd1498Szrj if (heads[INC_QUOTE])
406*38fd1498Szrj free_path (heads[INC_QUOTE], REASON_QUIET);
407*38fd1498Szrj if (tails[INC_QUOTE])
408*38fd1498Szrj free_path (tails[INC_QUOTE], REASON_QUIET);
409*38fd1498Szrj heads[INC_QUOTE] = heads[INC_BRACKET];
410*38fd1498Szrj tails[INC_QUOTE] = tails[INC_BRACKET];
411*38fd1498Szrj heads[INC_BRACKET] = NULL;
412*38fd1498Szrj tails[INC_BRACKET] = NULL;
413*38fd1498Szrj /* This is NOT redundant. */
414*38fd1498Szrj quote_ignores_source_dir = true;
415*38fd1498Szrj }
416*38fd1498Szrj
417*38fd1498Szrj /* Add P to the chain specified by CHAIN. */
418*38fd1498Szrj
419*38fd1498Szrj void
add_cpp_dir_path(cpp_dir * p,incpath_kind chain)420*38fd1498Szrj add_cpp_dir_path (cpp_dir *p, incpath_kind chain)
421*38fd1498Szrj {
422*38fd1498Szrj if (tails[chain])
423*38fd1498Szrj tails[chain]->next = p;
424*38fd1498Szrj else
425*38fd1498Szrj heads[chain] = p;
426*38fd1498Szrj tails[chain] = p;
427*38fd1498Szrj }
428*38fd1498Szrj
429*38fd1498Szrj /* Add PATH to the include chain CHAIN. PATH must be malloc-ed and
430*38fd1498Szrj NUL-terminated. */
431*38fd1498Szrj void
add_path(char * path,incpath_kind chain,int cxx_aware,bool user_supplied_p)432*38fd1498Szrj add_path (char *path, incpath_kind chain, int cxx_aware, bool user_supplied_p)
433*38fd1498Szrj {
434*38fd1498Szrj cpp_dir *p;
435*38fd1498Szrj
436*38fd1498Szrj #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
437*38fd1498Szrj /* Remove unnecessary trailing slashes. On some versions of MS
438*38fd1498Szrj Windows, trailing _forward_ slashes cause no problems for stat().
439*38fd1498Szrj On newer versions, stat() does not recognize a directory that ends
440*38fd1498Szrj in a '\\' or '/', unless it is a drive root dir, such as "c:/",
441*38fd1498Szrj where it is obligatory. */
442*38fd1498Szrj int pathlen = strlen (path);
443*38fd1498Szrj char* end = path + pathlen - 1;
444*38fd1498Szrj /* Preserve the lead '/' or lead "c:/". */
445*38fd1498Szrj char* start = path + (pathlen > 2 && path[1] == ':' ? 3 : 1);
446*38fd1498Szrj
447*38fd1498Szrj for (; end > start && IS_DIR_SEPARATOR (*end); end--)
448*38fd1498Szrj *end = 0;
449*38fd1498Szrj #endif
450*38fd1498Szrj
451*38fd1498Szrj p = XNEW (cpp_dir);
452*38fd1498Szrj p->next = NULL;
453*38fd1498Szrj p->name = path;
454*38fd1498Szrj #ifndef INO_T_EQ
455*38fd1498Szrj p->canonical_name = lrealpath (path);
456*38fd1498Szrj #endif
457*38fd1498Szrj if (chain == INC_SYSTEM || chain == INC_AFTER)
458*38fd1498Szrj p->sysp = 1 + !cxx_aware;
459*38fd1498Szrj else
460*38fd1498Szrj p->sysp = 0;
461*38fd1498Szrj p->construct = 0;
462*38fd1498Szrj p->user_supplied_p = user_supplied_p;
463*38fd1498Szrj
464*38fd1498Szrj add_cpp_dir_path (p, chain);
465*38fd1498Szrj }
466*38fd1498Szrj
467*38fd1498Szrj /* Exported function to handle include chain merging, duplicate
468*38fd1498Szrj removal, and registration with cpplib. */
469*38fd1498Szrj void
register_include_chains(cpp_reader * pfile,const char * sysroot,const char * iprefix,const char * imultilib,int stdinc,int cxx_stdinc,int verbose)470*38fd1498Szrj register_include_chains (cpp_reader *pfile, const char *sysroot,
471*38fd1498Szrj const char *iprefix, const char *imultilib,
472*38fd1498Szrj int stdinc, int cxx_stdinc, int verbose)
473*38fd1498Szrj {
474*38fd1498Szrj static const char *const lang_env_vars[] =
475*38fd1498Szrj { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
476*38fd1498Szrj "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
477*38fd1498Szrj cpp_options *cpp_opts = cpp_get_options (pfile);
478*38fd1498Szrj size_t idx = (cpp_opts->objc ? 2: 0);
479*38fd1498Szrj
480*38fd1498Szrj if (cpp_opts->cplusplus)
481*38fd1498Szrj idx++;
482*38fd1498Szrj else
483*38fd1498Szrj cxx_stdinc = false;
484*38fd1498Szrj
485*38fd1498Szrj /* CPATH and language-dependent environment variables may add to the
486*38fd1498Szrj include chain. */
487*38fd1498Szrj add_env_var_paths ("CPATH", INC_BRACKET);
488*38fd1498Szrj add_env_var_paths (lang_env_vars[idx], INC_SYSTEM);
489*38fd1498Szrj
490*38fd1498Szrj target_c_incpath.extra_pre_includes (sysroot, iprefix, stdinc);
491*38fd1498Szrj
492*38fd1498Szrj /* Finally chain on the standard directories. */
493*38fd1498Szrj if (stdinc)
494*38fd1498Szrj add_standard_paths (sysroot, iprefix, imultilib, cxx_stdinc);
495*38fd1498Szrj
496*38fd1498Szrj target_c_incpath.extra_includes (sysroot, iprefix, stdinc);
497*38fd1498Szrj
498*38fd1498Szrj merge_include_chains (sysroot, pfile, verbose);
499*38fd1498Szrj
500*38fd1498Szrj cpp_set_include_chains (pfile, heads[INC_QUOTE], heads[INC_BRACKET],
501*38fd1498Szrj quote_ignores_source_dir);
502*38fd1498Szrj }
503*38fd1498Szrj
504*38fd1498Szrj /* Return the current chain of cpp dirs. */
505*38fd1498Szrj
506*38fd1498Szrj struct cpp_dir *
get_added_cpp_dirs(incpath_kind chain)507*38fd1498Szrj get_added_cpp_dirs (incpath_kind chain)
508*38fd1498Szrj {
509*38fd1498Szrj return heads[chain];
510*38fd1498Szrj }
511*38fd1498Szrj
512*38fd1498Szrj #if !(defined TARGET_EXTRA_INCLUDES) || !(defined TARGET_EXTRA_PRE_INCLUDES)
hook_void_charptr_charptr_int(const char * sysroot ATTRIBUTE_UNUSED,const char * iprefix ATTRIBUTE_UNUSED,int stdinc ATTRIBUTE_UNUSED)513*38fd1498Szrj static void hook_void_charptr_charptr_int (const char *sysroot ATTRIBUTE_UNUSED,
514*38fd1498Szrj const char *iprefix ATTRIBUTE_UNUSED,
515*38fd1498Szrj int stdinc ATTRIBUTE_UNUSED)
516*38fd1498Szrj {
517*38fd1498Szrj }
518*38fd1498Szrj #endif
519*38fd1498Szrj
520*38fd1498Szrj #ifndef TARGET_EXTRA_INCLUDES
521*38fd1498Szrj #define TARGET_EXTRA_INCLUDES hook_void_charptr_charptr_int
522*38fd1498Szrj #endif
523*38fd1498Szrj #ifndef TARGET_EXTRA_PRE_INCLUDES
524*38fd1498Szrj #define TARGET_EXTRA_PRE_INCLUDES hook_void_charptr_charptr_int
525*38fd1498Szrj #endif
526*38fd1498Szrj
527*38fd1498Szrj struct target_c_incpath_s target_c_incpath = { TARGET_EXTRA_PRE_INCLUDES, TARGET_EXTRA_INCLUDES };
528*38fd1498Szrj
529