| /* d-incpath.cc -- Set up combined import paths for the D frontend. |
| Copyright (C) 2006-2022 Free Software Foundation, Inc. |
| |
| GCC 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 3, or (at your option) |
| any later version. |
| |
| GCC 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 GCC; see the file COPYING3. If not see |
| <http://www.gnu.org/licenses/>. */ |
| |
| #include "config.h" |
| #include "system.h" |
| #include "coretypes.h" |
| |
| #include "dmd/globals.h" |
| #include "d-frontend.h" |
| |
| #include "cppdefault.h" |
| |
| /* Look for directories that start with the standard prefix. |
| "Translate" them, i.e: replace /usr/local/lib/gcc with |
| IPREFIX and search them first. Based on incpath.cc. */ |
| |
| static char * |
| prefixed_path (const char *path, const char *iprefix) |
| { |
| if (cpp_relocated () && cpp_PREFIX_len != 0) |
| { |
| if (!filename_ncmp (path, cpp_PREFIX, cpp_PREFIX_len)) |
| { |
| static const char *relocated_prefix; |
| /* If this path starts with the configure-time prefix, |
| but the compiler has been relocated, replace it |
| with the run-time prefix. */ |
| if (!relocated_prefix) |
| { |
| /* Make relative prefix expects the first argument |
| to be a program, not a directory. */ |
| char *dummy = concat (gcc_exec_prefix, "dummy", NULL); |
| relocated_prefix |
| = make_relative_prefix (dummy, |
| cpp_EXEC_PREFIX, |
| cpp_PREFIX); |
| free (dummy); |
| } |
| |
| return concat (relocated_prefix, path + cpp_PREFIX_len, NULL); |
| } |
| } |
| |
| if (iprefix && cpp_GCC_INCLUDE_DIR_len != 0) |
| { |
| if (!filename_ncmp (path, cpp_GCC_INCLUDE_DIR, cpp_GCC_INCLUDE_DIR_len)) |
| return concat (iprefix, path + cpp_GCC_INCLUDE_DIR_len, NULL); |
| } |
| |
| return xstrdup (path); |
| } |
| |
| /* Add PATHS to the global import lookup path. */ |
| |
| static void |
| add_globalpaths (Strings *paths) |
| { |
| if (paths) |
| { |
| if (!global.path) |
| global.path = d_gc_malloc<Strings> (); |
| |
| for (size_t i = 0; i < paths->length; i++) |
| { |
| const char *path = (*paths)[i]; |
| const char *target = lrealpath (path); |
| |
| if (target == NULL || !FileName::exists (target)) |
| { |
| if (target) |
| free (CONST_CAST (char *, target)); |
| continue; |
| } |
| |
| global.path->push (target); |
| } |
| } |
| } |
| |
| /* Add PATHS to the global file import lookup path. */ |
| |
| static void |
| add_filepaths (Strings *paths) |
| { |
| if (paths) |
| { |
| if (!global.filePath) |
| global.filePath = d_gc_malloc<Strings> (); |
| |
| for (size_t i = 0; i < paths->length; i++) |
| { |
| const char *path = (*paths)[i]; |
| const char *target = lrealpath (path); |
| |
| if (!FileName::exists (target)) |
| { |
| free (CONST_CAST (char *, target)); |
| continue; |
| } |
| |
| global.filePath->push (target); |
| } |
| } |
| } |
| |
| /* Add all search directories to compiler runtime. |
| if STDINC, also include standard library paths. */ |
| |
| void |
| add_import_paths (const char *iprefix, const char *imultilib, bool stdinc) |
| { |
| if (stdinc) |
| { |
| for (const default_include *p = cpp_include_defaults; p->fname; p++) |
| { |
| char *path; |
| |
| /* Ignore C++ paths. */ |
| if (p->cplusplus) |
| continue; |
| |
| if (!p->add_sysroot) |
| path = prefixed_path (p->fname, iprefix); |
| else |
| path = xstrdup (p->fname); |
| |
| /* Add D-specific suffix. */ |
| path = concat (path, "/d", NULL); |
| |
| /* Ignore duplicate entries. */ |
| bool found = false; |
| for (size_t i = 0; i < global.params.imppath->length; i++) |
| { |
| if (strcmp (path, (*global.params.imppath)[i]) == 0) |
| { |
| found = true; |
| break; |
| } |
| } |
| |
| if (found) |
| { |
| free (path); |
| continue; |
| } |
| |
| /* Multilib support. */ |
| if (imultilib) |
| { |
| char *target_path = concat (path, "/", imultilib, NULL); |
| global.params.imppath->shift (target_path); |
| } |
| |
| global.params.imppath->shift (path); |
| } |
| } |
| |
| /* Add import search paths. */ |
| if (global.params.imppath) |
| { |
| for (size_t i = 0; i < global.params.imppath->length; i++) |
| { |
| const char *path = (*global.params.imppath)[i]; |
| if (path) |
| add_globalpaths (FileName::splitPath (path)); |
| } |
| } |
| |
| /* Add string import search paths. */ |
| if (global.params.fileImppath) |
| { |
| for (size_t i = 0; i < global.params.fileImppath->length; i++) |
| { |
| const char *path = (*global.params.fileImppath)[i]; |
| if (path) |
| add_filepaths (FileName::splitPath (path)); |
| } |
| } |
| } |
| |