00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "machmode.h"
00026 #include "target.h"
00027 #include "tm.h"
00028 #include "cpplib.h"
00029 #include "prefix.h"
00030 #include "intl.h"
00031 #include "c-incpath.h"
00032 #include "cppdefault.h"
00033
00034
00035
00036
00037 #ifdef VMS
00038 # define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
00039 # define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
00040 #else
00041 # if (defined _WIN32 && !defined (_UWIN)) || defined __MSDOS__
00042 # define INO_T_EQ(A, B) 0
00043 # else
00044 # define INO_T_EQ(A, B) ((A) == (B))
00045 # endif
00046 # define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
00047 #endif
00048
00049 static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
00050
00051 static void add_env_var_paths (const char *, int);
00052 static void add_standard_paths (const char *, const char *, const char *, int);
00053 static void free_path (struct cpp_dir *, int);
00054 static void merge_include_chains (cpp_reader *, int);
00055 static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *,
00056 struct cpp_dir *,
00057 struct cpp_dir *, int);
00058
00059
00060 static struct cpp_dir *heads[4];
00061 static struct cpp_dir *tails[4];
00062 static bool quote_ignores_source_dir;
00063 enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS };
00064
00065
00066 static void
00067 free_path (struct cpp_dir *path, int reason)
00068 {
00069 switch (reason)
00070 {
00071 case REASON_DUP:
00072 case REASON_DUP_SYS:
00073 fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), path->name);
00074 if (reason == REASON_DUP_SYS)
00075 fprintf (stderr,
00076 _(" as it is a non-system directory that duplicates a system directory\n"));
00077 break;
00078
00079 case REASON_NOENT:
00080 fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"),
00081 path->name);
00082 break;
00083
00084 case REASON_QUIET:
00085 default:
00086 break;
00087 }
00088
00089 free (path->name);
00090 free (path);
00091 }
00092
00093
00094
00095 static void
00096 add_env_var_paths (const char *env_var, int chain)
00097 {
00098 char *p, *q, *path;
00099
00100 GET_ENVIRONMENT (q, env_var);
00101
00102 if (!q)
00103 return;
00104
00105 for (p = q; *q; p = q + 1)
00106 {
00107 q = p;
00108 while (*q != 0 && *q != PATH_SEPARATOR)
00109 q++;
00110
00111 if (p == q)
00112 path = xstrdup (".");
00113 else
00114 {
00115 path = XNEWVEC (char, q - p + 1);
00116 memcpy (path, p, q - p);
00117 path[q - p] = '\0';
00118 }
00119
00120 add_path (path, chain, chain == SYSTEM, false);
00121 }
00122 }
00123
00124
00125 static void
00126 add_standard_paths (const char *sysroot, const char *iprefix,
00127 const char *imultilib, int cxx_stdinc)
00128 {
00129 const struct default_include *p;
00130 size_t len;
00131
00132 if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0)
00133 {
00134
00135
00136
00137 for (p = cpp_include_defaults; p->fname; p++)
00138 {
00139 if (!p->cplusplus || cxx_stdinc)
00140 {
00141
00142
00143
00144 if (sysroot && p->add_sysroot)
00145 continue;
00146 if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
00147 {
00148 char *str = concat (iprefix, p->fname + len, NULL);
00149 if (p->multilib && imultilib)
00150 str = concat (str, dir_separator_str, imultilib, NULL);
00151 add_path (str, SYSTEM, p->cxx_aware, false);
00152 }
00153 }
00154 }
00155 }
00156
00157 for (p = cpp_include_defaults; p->fname; p++)
00158 {
00159 if (!p->cplusplus || cxx_stdinc)
00160 {
00161 char *str;
00162
00163
00164 if (sysroot && p->add_sysroot)
00165 str = concat (sysroot, p->fname, NULL);
00166 else
00167 str = update_path (p->fname, p->component);
00168
00169 if (p->multilib && imultilib)
00170 str = concat (str, dir_separator_str, imultilib, NULL);
00171
00172 add_path (str, SYSTEM, p->cxx_aware, false);
00173 }
00174 }
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184 static struct cpp_dir *
00185 remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
00186 struct cpp_dir *system, struct cpp_dir *join,
00187 int verbose)
00188 {
00189 struct cpp_dir **pcur, *tmp, *cur;
00190 struct stat st;
00191
00192 for (pcur = &head; *pcur; )
00193 {
00194 int reason = REASON_QUIET;
00195
00196 cur = *pcur;
00197
00198 if (stat (cur->name, &st))
00199 {
00200
00201 if (errno != ENOENT)
00202 cpp_errno (pfile, CPP_DL_ERROR, cur->name);
00203 else
00204 {
00205
00206 cpp_options *opts = cpp_get_options (pfile);
00207 if (opts->warn_missing_include_dirs && cur->user_supplied_p)
00208 cpp_errno (pfile, CPP_DL_WARNING, cur->name);
00209 reason = REASON_NOENT;
00210 }
00211 }
00212 else if (!S_ISDIR (st.st_mode))
00213 cpp_error_with_line (pfile, CPP_DL_ERROR, 0, 0,
00214 "%s: not a directory", cur->name);
00215 else
00216 {
00217 INO_T_COPY (cur->ino, st.st_ino);
00218 cur->dev = st.st_dev;
00219
00220
00221 reason = REASON_DUP_SYS;
00222 for (tmp = system; tmp; tmp = tmp->next)
00223 if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev
00224 && cur->construct == tmp->construct)
00225 break;
00226
00227 if (!tmp)
00228 {
00229
00230 reason = REASON_DUP;
00231 for (tmp = head; tmp != cur; tmp = tmp->next)
00232 if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev
00233 && cur->construct == tmp->construct)
00234 break;
00235
00236 if (tmp == cur
00237
00238 && !(cur->next == NULL && join
00239 && INO_T_EQ (cur->ino, join->ino)
00240 && cur->dev == join->dev
00241 && cur->construct == join->construct))
00242 {
00243
00244 pcur = &cur->next;
00245 continue;
00246 }
00247 }
00248 }
00249
00250
00251 *pcur = cur->next;
00252 free_path (cur, verbose ? reason: REASON_QUIET);
00253 }
00254
00255 *pcur = join;
00256 return head;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 static void
00270 merge_include_chains (cpp_reader *pfile, int verbose)
00271 {
00272
00273
00274 if (heads[SYSTEM])
00275 tails[SYSTEM]->next = heads[AFTER];
00276 else
00277 heads[SYSTEM] = heads[AFTER];
00278 heads[SYSTEM] = remove_duplicates (pfile, heads[SYSTEM], 0, 0, verbose);
00279
00280
00281
00282 heads[BRACKET] = remove_duplicates (pfile, heads[BRACKET], heads[SYSTEM],
00283 heads[SYSTEM], verbose);
00284
00285
00286
00287 heads[QUOTE] = remove_duplicates (pfile, heads[QUOTE], heads[SYSTEM],
00288 heads[BRACKET], verbose);
00289
00290
00291 if (verbose)
00292 {
00293 struct cpp_dir *p;
00294
00295 fprintf (stderr, _("#include \"...\" search starts here:\n"));
00296 for (p = heads[QUOTE];; p = p->next)
00297 {
00298 if (p == heads[BRACKET])
00299 fprintf (stderr, _("#include <...> search starts here:\n"));
00300 if (!p)
00301 break;
00302 fprintf (stderr, " %s\n", p->name);
00303 }
00304 fprintf (stderr, _("End of search list.\n"));
00305 }
00306 }
00307
00308
00309
00310
00311
00312 void
00313 split_quote_chain (void)
00314 {
00315 heads[QUOTE] = heads[BRACKET];
00316 tails[QUOTE] = tails[BRACKET];
00317 heads[BRACKET] = NULL;
00318 tails[BRACKET] = NULL;
00319
00320 quote_ignores_source_dir = true;
00321 }
00322
00323
00324
00325 void
00326 add_cpp_dir_path (cpp_dir *p, int chain)
00327 {
00328 if (tails[chain])
00329 tails[chain]->next = p;
00330 else
00331 heads[chain] = p;
00332 tails[chain] = p;
00333 }
00334
00335
00336
00337 void
00338 add_path (char *path, int chain, int cxx_aware, bool user_supplied_p)
00339 {
00340 cpp_dir *p;
00341
00342 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
00343
00344
00345
00346
00347 char* c;
00348 for (c = path; *c; c++)
00349 if (*c == '\\') *c = '/';
00350 #endif
00351
00352 p = XNEW (cpp_dir);
00353 p->next = NULL;
00354 p->name = path;
00355 if (chain == SYSTEM || chain == AFTER)
00356 p->sysp = 1 + !cxx_aware;
00357 else
00358 p->sysp = 0;
00359 p->construct = 0;
00360 p->user_supplied_p = user_supplied_p;
00361
00362 add_cpp_dir_path (p, chain);
00363 }
00364
00365
00366
00367 void
00368 register_include_chains (cpp_reader *pfile, const char *sysroot,
00369 const char *iprefix, const char *imultilib,
00370 int stdinc, int cxx_stdinc, int verbose)
00371 {
00372 static const char *const lang_env_vars[] =
00373 { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
00374 "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
00375 cpp_options *cpp_opts = cpp_get_options (pfile);
00376 size_t idx = (cpp_opts->objc ? 2: 0);
00377
00378 if (cpp_opts->cplusplus)
00379 idx++;
00380 else
00381 cxx_stdinc = false;
00382
00383
00384
00385 add_env_var_paths ("CPATH", BRACKET);
00386 add_env_var_paths (lang_env_vars[idx], SYSTEM);
00387
00388 target_c_incpath.extra_pre_includes (sysroot, iprefix, stdinc);
00389
00390
00391 if (stdinc)
00392 add_standard_paths (sysroot, iprefix, imultilib, cxx_stdinc);
00393
00394 target_c_incpath.extra_includes (sysroot, iprefix, stdinc);
00395
00396 merge_include_chains (pfile, verbose);
00397
00398 cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET],
00399 quote_ignores_source_dir);
00400 }
00401 #if !(defined TARGET_EXTRA_INCLUDES) || !(defined TARGET_EXTRA_PRE_INCLUDES)
00402 static void hook_void_charptr_charptr_int (const char *sysroot ATTRIBUTE_UNUSED,
00403 const char *iprefix ATTRIBUTE_UNUSED,
00404 int stdinc ATTRIBUTE_UNUSED)
00405 {
00406 }
00407 #endif
00408
00409 #ifndef TARGET_EXTRA_INCLUDES
00410 #define TARGET_EXTRA_INCLUDES hook_void_charptr_charptr_int
00411 #endif
00412 #ifndef TARGET_EXTRA_PRE_INCLUDES
00413 #define TARGET_EXTRA_PRE_INCLUDES hook_void_charptr_charptr_int
00414 #endif
00415
00416 struct target_c_incpath_s target_c_incpath = { TARGET_EXTRA_PRE_INCLUDES, TARGET_EXTRA_INCLUDES };
00417