OSDN Git Service

* gcc.target/xstormy16: New test directory.
[pf3gnuchains/gcc-fork.git] / gcc / c-incpath.c
1 /* Set up combined include path chain for the preprocessor.
2    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4
5    Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003.
6
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "machmode.h"
25 #include "target.h"
26 #include "tm.h"
27 #include "cpplib.h"
28 #include "prefix.h"
29 #include "intl.h"
30 #include "c-incpath.h"
31 #include "cppdefault.h"
32
33 /* Windows does not natively support inodes, and neither does MSDOS.
34    Cygwin's emulation can generate non-unique inodes, so don't use it.
35    VMS has non-numeric inodes.  */
36 #ifdef VMS
37 # define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
38 # define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
39 #else
40 # if (defined _WIN32 && !defined (_UWIN)) || defined __MSDOS__
41 #  define INO_T_EQ(A, B) 0
42 # else
43 #  define INO_T_EQ(A, B) ((A) == (B))
44 # endif
45 # define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
46 #endif
47
48 static void add_env_var_paths (const char *, int);
49 static void add_standard_paths (const char *, const char *, int);
50 static void free_path (struct cpp_dir *, int);
51 static void merge_include_chains (cpp_reader *, int);
52 static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *,
53                                            struct cpp_dir *,
54                                            struct cpp_dir *, int);
55
56 /* Include chains heads and tails.  */
57 static struct cpp_dir *heads[4];
58 static struct cpp_dir *tails[4];
59 static bool quote_ignores_source_dir;
60 enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS };
61
62 /* Free an element of the include chain, possibly giving a reason.  */
63 static void
64 free_path (struct cpp_dir *path, int reason)
65 {
66   switch (reason)
67     {
68     case REASON_DUP:
69     case REASON_DUP_SYS:
70       fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), path->name);
71       if (reason == REASON_DUP_SYS)
72         fprintf (stderr,
73  _("  as it is a non-system directory that duplicates a system directory\n"));
74       break;
75
76     case REASON_NOENT:
77       fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"),
78                path->name);
79       break;
80
81     case REASON_QUIET:
82     default:
83       break;
84     }
85
86   free (path->name);
87   free (path);
88 }
89
90 /* Read ENV_VAR for a PATH_SEPARATOR-separated list of file names; and
91    append all the names to the search path CHAIN.  */
92 static void
93 add_env_var_paths (const char *env_var, int chain)
94 {
95   char *p, *q, *path;
96
97   GET_ENVIRONMENT (q, env_var);
98
99   if (!q)
100     return;
101
102   for (p = q; *q; p = q + 1)
103     {
104       q = p;
105       while (*q != 0 && *q != PATH_SEPARATOR)
106         q++;
107
108       if (p == q)
109         path = xstrdup (".");
110       else
111         {
112           path = xmalloc (q - p + 1);
113           memcpy (path, p, q - p);
114           path[q - p] = '\0';
115         }
116
117       add_path (path, chain, chain == SYSTEM, false);
118     }
119 }
120
121 /* Append the standard include chain defined in cppdefault.c.  */
122 static void
123 add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
124 {
125   const struct default_include *p;
126   size_t len;
127
128   if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0)
129     {
130       /* Look for directories that start with the standard prefix.
131          "Translate" them, i.e. replace /usr/local/lib/gcc... with
132          IPREFIX and search them first.  */
133       for (p = cpp_include_defaults; p->fname; p++)
134         {
135           if (!p->cplusplus || cxx_stdinc)
136             {
137               /* Should we be translating sysrooted dirs too?  Assume
138                  that iprefix and sysroot are mutually exclusive, for
139                  now.  */
140               if (sysroot && p->add_sysroot)
141                 continue;
142               if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
143                 {
144                   char *str = concat (iprefix, p->fname + len, NULL);
145                   add_path (str, SYSTEM, p->cxx_aware, false);
146                 }
147             }
148         }
149     }
150
151   for (p = cpp_include_defaults; p->fname; p++)
152     {
153       if (!p->cplusplus || cxx_stdinc)
154         {
155           char *str;
156
157           /* Should this directory start with the sysroot?  */
158           if (sysroot && p->add_sysroot)
159             str = concat (sysroot, p->fname, NULL);
160           else
161             str = update_path (p->fname, p->component);
162
163           add_path (str, SYSTEM, p->cxx_aware, false);
164         }
165     }
166 }
167
168 /* For each duplicate path in chain HEAD, keep just the first one.
169    Remove each path in chain HEAD that also exists in chain SYSTEM.
170    Set the NEXT pointer of the last path in the resulting chain to
171    JOIN, unless it duplicates JOIN in which case the last path is
172    removed.  Return the head of the resulting chain.  Any of HEAD,
173    JOIN and SYSTEM can be NULL.  */
174
175 static struct cpp_dir *
176 remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
177                    struct cpp_dir *system, struct cpp_dir *join,
178                    int verbose)
179 {
180   struct cpp_dir **pcur, *tmp, *cur;
181   struct stat st;
182
183   for (pcur = &head; *pcur; )
184     {
185       int reason = REASON_QUIET;
186
187       cur = *pcur;
188
189       if (stat (cur->name, &st))
190         {
191           /* Dirs that don't exist are silently ignored, unless verbose.  */
192           if (errno != ENOENT)
193             cpp_errno (pfile, CPP_DL_ERROR, cur->name);
194           else
195             {
196               /* If -Wmissing-include-dirs is given, warn.  */
197               cpp_options *opts = cpp_get_options (pfile);
198               if (opts->warn_missing_include_dirs && cur->user_supplied_p)
199                 cpp_errno (pfile, CPP_DL_WARNING, cur->name);
200               reason = REASON_NOENT;
201             }
202         }
203       else if (!S_ISDIR (st.st_mode))
204         cpp_error_with_line (pfile, CPP_DL_ERROR, 0, 0,
205                              "%s: not a directory", cur->name);
206       else
207         {
208           INO_T_COPY (cur->ino, st.st_ino);
209           cur->dev  = st.st_dev;
210
211           /* Remove this one if it is in the system chain.  */
212           reason = REASON_DUP_SYS;
213           for (tmp = system; tmp; tmp = tmp->next)
214             if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev)
215               break;
216
217           if (!tmp)
218             {
219               /* Duplicate of something earlier in the same chain?  */
220               reason = REASON_DUP;
221               for (tmp = head; tmp != cur; tmp = tmp->next)
222                 if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev)
223                   break;
224
225               if (tmp == cur
226                   /* Last in the chain and duplicate of JOIN?  */
227                   && !(cur->next == NULL && join
228                        && INO_T_EQ (cur->ino, join->ino)
229                        && cur->dev == join->dev))
230                 {
231                   /* Unique, so keep this directory.  */
232                   pcur = &cur->next;
233                   continue;
234                 }
235             }
236         }
237
238       /* Remove this entry from the chain.  */
239       *pcur = cur->next;
240       free_path (cur, verbose ? reason: REASON_QUIET);
241     }
242
243   *pcur = join;
244   return head;
245 }
246
247 /* Merge the four include chains together in the order quote, bracket,
248    system, after.  Remove duplicate dirs (as determined by
249    INO_T_EQ()).
250
251    We can't just merge the lists and then uniquify them because then
252    we may lose directories from the <> search path that should be
253    there; consider -iquote foo -iquote bar -Ifoo -Iquux.  It is
254    however safe to treat -iquote bar -iquote foo -Ifoo -Iquux as if
255    written -iquote bar -Ifoo -Iquux.  */
256
257 static void
258 merge_include_chains (cpp_reader *pfile, int verbose)
259 {
260   /* Join the SYSTEM and AFTER chains.  Remove duplicates in the
261      resulting SYSTEM chain.  */
262   if (heads[SYSTEM])
263     tails[SYSTEM]->next = heads[AFTER];
264   else
265     heads[SYSTEM] = heads[AFTER];
266   heads[SYSTEM] = remove_duplicates (pfile, heads[SYSTEM], 0, 0, verbose);
267
268   /* Remove duplicates from BRACKET that are in itself or SYSTEM, and
269      join it to SYSTEM.  */
270   heads[BRACKET] = remove_duplicates (pfile, heads[BRACKET], heads[SYSTEM],
271                                       heads[SYSTEM], verbose);
272
273   /* Remove duplicates from QUOTE that are in itself or SYSTEM, and
274      join it to BRACKET.  */
275   heads[QUOTE] = remove_duplicates (pfile, heads[QUOTE], heads[SYSTEM],
276                                     heads[BRACKET], verbose);
277
278   /* If verbose, print the list of dirs to search.  */
279   if (verbose)
280     {
281       struct cpp_dir *p;
282
283       fprintf (stderr, _("#include \"...\" search starts here:\n"));
284       for (p = heads[QUOTE];; p = p->next)
285         {
286           if (p == heads[BRACKET])
287             fprintf (stderr, _("#include <...> search starts here:\n"));
288           if (!p)
289             break;
290           fprintf (stderr, " %s\n", p->name);
291         }
292       fprintf (stderr, _("End of search list.\n"));
293     }
294 }
295
296 /* Use given -I paths for #include "..." but not #include <...>, and
297    don't search the directory of the present file for #include "...".
298    (Note that -I. -I- is not the same as the default setup; -I. uses
299    the compiler's working dir.)  */
300 void
301 split_quote_chain (void)
302 {
303   heads[QUOTE] = heads[BRACKET];
304   tails[QUOTE] = tails[BRACKET];
305   heads[BRACKET] = NULL;
306   tails[BRACKET] = NULL;
307   /* This is NOT redundant.  */
308   quote_ignores_source_dir = true;
309 }
310
311 /* Add P to the chain specified by CHAIN.  */
312
313 void
314 add_cpp_dir_path (cpp_dir *p, int chain)
315 {
316   if (tails[chain])
317     tails[chain]->next = p;
318   else
319     heads[chain] = p;
320   tails[chain] = p;
321 }
322
323 /* Add PATH to the include chain CHAIN. PATH must be malloc-ed and
324    NUL-terminated.  */
325 void
326 add_path (char *path, int chain, int cxx_aware, bool user_supplied_p)
327 {
328   cpp_dir *p;
329
330 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
331   /* Convert all backslashes to slashes.  The native CRT stat()
332      function does not recognise a directory that ends in a backslash
333      (unless it is a drive root dir, such "c:\").  Forward slashes,
334      trailing or otherwise, cause no problems for stat().  */
335   char* c;
336   for (c = path; *c; c++)
337     if (*c == '\\') *c = '/';
338 #endif
339
340   p = xmalloc (sizeof (cpp_dir));
341   p->next = NULL;
342   p->name = path;
343   if (chain == SYSTEM || chain == AFTER)
344     p->sysp = 1 + !cxx_aware;
345   else
346     p->sysp = 0;
347   p->construct = 0;
348   p->user_supplied_p = user_supplied_p;
349
350   add_cpp_dir_path (p, chain);
351 }
352
353 /* Exported function to handle include chain merging, duplicate
354    removal, and registration with cpplib.  */
355 void
356 register_include_chains (cpp_reader *pfile, const char *sysroot,
357                          const char *iprefix, int stdinc, int cxx_stdinc,
358                          int verbose)
359 {
360   static const char *const lang_env_vars[] =
361     { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
362       "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
363   cpp_options *cpp_opts = cpp_get_options (pfile);
364   size_t idx = (cpp_opts->objc ? 2: 0);
365
366   if (cpp_opts->cplusplus)
367     idx++;
368   else
369     cxx_stdinc = false;
370
371   /* CPATH and language-dependent environment variables may add to the
372      include chain.  */
373   add_env_var_paths ("CPATH", BRACKET);
374   add_env_var_paths (lang_env_vars[idx], SYSTEM);
375   
376   target_c_incpath.extra_pre_includes (sysroot, iprefix, stdinc);
377
378   /* Finally chain on the standard directories.  */
379   if (stdinc)
380     add_standard_paths (sysroot, iprefix, cxx_stdinc);
381
382   target_c_incpath.extra_includes (sysroot, iprefix, stdinc);
383
384   merge_include_chains (pfile, verbose);
385
386   cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET],
387                           quote_ignores_source_dir);
388 }
389 #if !(defined TARGET_EXTRA_INCLUDES) || !(defined TARGET_EXTRA_PRE_INCLUDES)
390 static void hook_void_charptr_charptr_int (const char *sysroot ATTRIBUTE_UNUSED,
391                                            const char *iprefix ATTRIBUTE_UNUSED,
392                                            int stdinc ATTRIBUTE_UNUSED)
393 {
394 }
395 #endif
396
397 #ifndef TARGET_EXTRA_INCLUDES
398 #define TARGET_EXTRA_INCLUDES hook_void_charptr_charptr_int
399 #endif
400 #ifndef TARGET_EXTRA_PRE_INCLUDES
401 #define TARGET_EXTRA_PRE_INCLUDES hook_void_charptr_charptr_int
402 #endif
403
404 struct target_c_incpath_s target_c_incpath = { TARGET_EXTRA_PRE_INCLUDES, TARGET_EXTRA_INCLUDES };
405