diff --git a/src/dmd/dmodule.d b/src/dmd/dmodule.d index 9a301265ef61..a782a3e041cc 100644 --- a/src/dmd/dmodule.d +++ b/src/dmd/dmodule.d @@ -51,113 +51,6 @@ import dmd.target; import dmd.utils; import dmd.visitor; -enum package_d = "package." ~ mars_ext; -enum package_di = "package." ~ hdr_ext; - -/******************************************** - * Look for the source file if it's different from filename. - * Look for .di, .d, directory, and along global.path. - * Does not open the file. - * Params: - * filename = as supplied by the user - * path = path to look for filename - * Returns: - * the found file name or - * `null` if it is not different from filename. - */ -const(char)[] lookForSourceFile(const char[] filename, const char*[] path) nothrow -{ - //printf("lookForSourceFile(`%.*s`)\n", cast(int)filename.length, filename.ptr); - /* Search along path[] for .di file, then .d file, then .i file, then .c file. - */ - const sdi = FileName.forceExt(filename, hdr_ext); - if (FileName.exists(sdi) == 1) - return sdi; - scope(exit) FileName.free(sdi.ptr); - - const sd = FileName.forceExt(filename, mars_ext); - if (FileName.exists(sd) == 1) - return sd; - scope(exit) FileName.free(sd.ptr); - - const si = FileName.forceExt(filename, i_ext); - if (FileName.exists(si) == 1) - return si; - scope(exit) FileName.free(si.ptr); - - const sc = FileName.forceExt(filename, c_ext); - if (FileName.exists(sc) == 1) - return sc; - scope(exit) FileName.free(sc.ptr); - - if (FileName.exists(filename) == 2) - { - /* The filename exists and it's a directory. - * Therefore, the result should be: filename/package.d - * iff filename/package.d is a file - */ - const ni = FileName.combine(filename, package_di); - if (FileName.exists(ni) == 1) - return ni; - FileName.free(ni.ptr); - - const n = FileName.combine(filename, package_d); - if (FileName.exists(n) == 1) - return n; - FileName.free(n.ptr); - } - if (FileName.absolute(filename)) - return null; - if (!path.length) - return null; - foreach (entry; path) - { - const p = entry.toDString(); - - const(char)[] n = FileName.combine(p, sdi); - if (FileName.exists(n) == 1) { - return n; - } - FileName.free(n.ptr); - - n = FileName.combine(p, sd); - if (FileName.exists(n) == 1) { - return n; - } - FileName.free(n.ptr); - - n = FileName.combine(p, si); - if (FileName.exists(n) == 1) { - return n; - } - FileName.free(n.ptr); - - n = FileName.combine(p, sc); - if (FileName.exists(n) == 1) { - return n; - } - FileName.free(n.ptr); - - const b = FileName.removeExt(filename); - n = FileName.combine(p, b); - FileName.free(b.ptr); - if (FileName.exists(n) == 2) - { - const n2i = FileName.combine(n, package_di); - if (FileName.exists(n2i) == 1) - return n2i; - FileName.free(n2i.ptr); - const n2 = FileName.combine(n, package_d); - if (FileName.exists(n2) == 1) { - return n2; - } - FileName.free(n2.ptr); - } - FileName.free(n.ptr); - } - return null; -} - // function used to call semantic3 on a module's dependencies void semantic3OnDependencies(Module m) { @@ -415,7 +308,7 @@ extern (C++) class Package : ScopeDsymbol packages ~= s.ident; reverse(packages); - if (lookForSourceFile(getFilename(packages, ident), global.path ? (*global.path)[] : null)) + if (FileManager.lookForSourceFile(getFilename(packages, ident), global.path ? (*global.path)[] : null)) Module.load(Loc.initial, packages, this.ident); else isPkgMod = PKG.package_; @@ -613,7 +506,7 @@ extern (C++) final class Module : Package // foo\bar\baz const(char)[] filename = getFilename(packages, ident); // Look for the source file - if (const result = lookForSourceFile(filename, global.path ? (*global.path)[] : null)) + if (const result = FileManager.lookForSourceFile(filename, global.path ? (*global.path)[] : null)) filename = result; // leaks auto m = new Module(loc, filename, ident, 0, 0); diff --git a/src/dmd/file_manager.d b/src/dmd/file_manager.d index 3fd0e8c21ccc..37d69b2a67af 100644 --- a/src/dmd/file_manager.d +++ b/src/dmd/file_manager.d @@ -14,11 +14,12 @@ import dmd.root.stringtable : StringTable; import dmd.root.file : File, FileBuffer; import dmd.root.filename : FileName; import dmd.root.string : toDString; -import dmd.arraytypes; -import dmd.dmodule : lookForSourceFile; -import dmd.globals : global; +import dmd.globals; import dmd.identifier; +enum package_d = "package." ~ mars_ext; +enum package_di = "package." ~ hdr_ext; + extern(C++) struct FileManager { private StringTable!(FileBuffer*) files; @@ -51,6 +52,110 @@ nothrow: } + /******************************************** + * Look for the source file if it's different from filename. + * Look for .di, .d, directory, and along global.path. + * Does not open the file. + * Params: + * filename = as supplied by the user + * path = path to look for filename + * Returns: + * the found file name or + * `null` if it is not different from filename. + */ + extern(D) static const(char)[] lookForSourceFile(const char[] filename, const char*[] path) nothrow + { + //printf("lookForSourceFile(`%.*s`)\n", cast(int)filename.length, filename.ptr); + /* Search along path[] for .di file, then .d file, then .i file, then .c file. + */ + const sdi = FileName.forceExt(filename, hdr_ext); + if (FileName.exists(sdi) == 1) + return sdi; + scope(exit) FileName.free(sdi.ptr); + + const sd = FileName.forceExt(filename, mars_ext); + if (FileName.exists(sd) == 1) + return sd; + scope(exit) FileName.free(sd.ptr); + + const si = FileName.forceExt(filename, i_ext); + if (FileName.exists(si) == 1) + return si; + scope(exit) FileName.free(si.ptr); + + const sc = FileName.forceExt(filename, c_ext); + if (FileName.exists(sc) == 1) + return sc; + scope(exit) FileName.free(sc.ptr); + + if (FileName.exists(filename) == 2) + { + /* The filename exists and it's a directory. + * Therefore, the result should be: filename/package.d + * iff filename/package.d is a file + */ + const ni = FileName.combine(filename, package_di); + if (FileName.exists(ni) == 1) + return ni; + FileName.free(ni.ptr); + + const n = FileName.combine(filename, package_d); + if (FileName.exists(n) == 1) + return n; + FileName.free(n.ptr); + } + if (FileName.absolute(filename)) + return null; + if (!path.length) + return null; + foreach (entry; path) + { + const p = entry.toDString(); + + const(char)[] n = FileName.combine(p, sdi); + if (FileName.exists(n) == 1) { + return n; + } + FileName.free(n.ptr); + + n = FileName.combine(p, sd); + if (FileName.exists(n) == 1) { + return n; + } + FileName.free(n.ptr); + + n = FileName.combine(p, si); + if (FileName.exists(n) == 1) { + return n; + } + FileName.free(n.ptr); + + n = FileName.combine(p, sc); + if (FileName.exists(n) == 1) { + return n; + } + FileName.free(n.ptr); + + const b = FileName.removeExt(filename); + n = FileName.combine(p, b); + FileName.free(b.ptr); + if (FileName.exists(n) == 2) + { + const n2i = FileName.combine(n, package_di); + if (FileName.exists(n2i) == 1) + return n2i; + FileName.free(n2i.ptr); + const n2 = FileName.combine(n, package_d); + if (FileName.exists(n2) == 1) { + return n2; + } + FileName.free(n2.ptr); + } + FileName.free(n.ptr); + } + return null; + } + /** * Looks up the given filename from the internal file buffer table. * If the file does not already exist within the table, it will be read from the filesystem.