From a37c4404584289192ee3370ecaa489b58a245b75 Mon Sep 17 00:00:00 2001 From: Geod24 Date: Mon, 27 Aug 2018 23:03:34 +0900 Subject: [PATCH 1/8] utils: Make toDString inout --- src/dmd/utils.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmd/utils.d b/src/dmd/utils.d index d02550cd02b5..ca5f37d912c0 100644 --- a/src/dmd/utils.d +++ b/src/dmd/utils.d @@ -135,7 +135,7 @@ extern (C++) void escapePath(OutBuffer* buf, const(char)* fname) } /// Slices a `\0`-terminated C-string, excluding the terminator -const(char)[] toDString (const(char)* s) pure nothrow @nogc +inout(char)[] toDString (inout(char)* s) pure nothrow @nogc { return s ? s[0 .. strlen(s)] : null; } From 0b9c67745e1e45fb72b11db4e1d41306b3b54ad2 Mon Sep 17 00:00:00 2001 From: Geod24 Date: Tue, 21 Aug 2018 09:48:42 +0900 Subject: [PATCH 2/8] Convert FileName.absolute to use D slices --- src/dmd/root/filename.d | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/dmd/root/filename.d b/src/dmd/root/filename.d index 61af71c09af2..ac7eb380d803 100644 --- a/src/dmd/root/filename.d +++ b/src/dmd/root/filename.d @@ -81,13 +81,23 @@ nothrow: */ extern (C++) static bool absolute(const(char)* name) pure { + return absolute(name.toDString); + } + + /// Ditto + extern (D) static bool absolute(const(char)[] name) pure + { + if (!name.length) + return false; + version (Windows) { - return (*name == '\\') || (*name == '/') || (*name && name[1] == ':'); + return (name[0] == '\\') || (name[0] == '/') + || (name.length >= 2 && name[1] == ':'); } else version (Posix) { - return (*name == '/'); + return (name[0] == '/'); } else { @@ -95,6 +105,12 @@ nothrow: } } + unittest + { + assert(absolute("/"[]) == true); + assert(absolute(""[]) == false); + } + /** Return the given name as an absolute path From d78750698fe44c8c7c3a30d951c1febf399ebba6 Mon Sep 17 00:00:00 2001 From: Geod24 Date: Mon, 27 Aug 2018 23:19:54 +0900 Subject: [PATCH 3/8] Convert FileName.exists to use D slice --- src/dmd/root/filename.d | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/dmd/root/filename.d b/src/dmd/root/filename.d index ac7eb380d803..5260d96f730d 100644 --- a/src/dmd/root/filename.d +++ b/src/dmd/root/filename.d @@ -640,12 +640,26 @@ nothrow: } } + /** + Check if the file the `path` points to exists + + Returns: + 0 if it does not exists + 1 if it exists and is not a directory + 2 if it exists and is a directory + */ extern (C++) static int exists(const(char)* name) + { + return exists(name.toDString); + } + + /// Ditto + extern (D) static int exists(const(char)[] name) { version (Posix) { stat_t st; - if (stat(name, &st) < 0) + if (name.toCStringThen!(v => stat(v.ptr, &st)) < 0) return 0; if (S_ISDIR(st.st_mode)) return 2; @@ -653,7 +667,7 @@ nothrow: } else version (Windows) { - return name.toWStringzThen!((wname) + return name.toCStringThen!(cstr => cstr.toWStringzThen!((wname) { const dw = GetFileAttributesW(&wname[0]); if (dw == -1) @@ -662,7 +676,7 @@ nothrow: return 2; else return 1; - }); + })); } else { From ec0c6d5d02f18f50b21482e3429ca575eacf018c Mon Sep 17 00:00:00 2001 From: Geod24 Date: Tue, 21 Aug 2018 09:48:50 +0900 Subject: [PATCH 4/8] Convert FileName.ext to use D slices --- src/dmd/root/filename.d | 52 ++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/dmd/root/filename.d b/src/dmd/root/filename.d index 5260d96f730d..f1577febe03f 100644 --- a/src/dmd/root/filename.d +++ b/src/dmd/root/filename.d @@ -136,34 +136,44 @@ nothrow: */ extern (C++) static const(char)* ext(const(char)* str) pure { - size_t len = strlen(str); - const(char)* e = str + len; - for (;;) + return ext(str.toDString).ptr; + } + + /// Ditto + extern (D) static const(char)[] ext(const(char)[] str) nothrow pure @safe @nogc + { + foreach_reverse (idx, char e; str) { - switch (*e) + switch (e) { case '.': - return e + 1; - version (Posix) - { - case '/': - break; - } - version (Windows) - { - case '\\': - case ':': - case '/': - break; - } + return str[idx + 1 .. $]; + version (Posix) + { + case '/': + return null; + } + version (Windows) + { + case '\\': + case ':': + case '/': + return null; + } default: - if (e == str) - break; - e--; continue; } - return null; } + return null; + } + + unittest + { + assert(ext("/foo/bar/dmd.conf"[]) == "conf"); + assert(ext("object.o"[]) == "o"); + assert(ext("/foo/bar/dmd"[]) == null); + assert(ext(".objdir.o/object"[]) == null); + assert(ext([]) == null); } extern (C++) const(char)* ext() const pure From ee11f59b78b0c9bb2fc22c0738591089f5a177a4 Mon Sep 17 00:00:00 2001 From: Geod24 Date: Mon, 27 Aug 2018 23:29:06 +0900 Subject: [PATCH 5/8] Convert FileName.equalsExt to D slice --- src/dmd/root/filename.d | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/dmd/root/filename.d b/src/dmd/root/filename.d index f1577febe03f..3942233592ad 100644 --- a/src/dmd/root/filename.d +++ b/src/dmd/root/filename.d @@ -511,16 +511,32 @@ nothrow: return defaultExt(name, ext); // doesn't have one } + /// Returns: + /// `true` if `name`'s extension is `ext` extern (C++) static bool equalsExt(const(char)* name, const(char)* ext) pure { - const(char)* e = FileName.ext(name); - if (!e && !ext) + return equalsExt(name.toDString, ext.toDString); + } + + /// Ditto + extern (D) static bool equalsExt(const(char)[] name, const(char)[] ext) pure + { + const e = FileName.ext(name); + if (!e.length && !ext.length) return true; - if (!e || !ext) + if (!e.length || !ext.length) return false; return FileName.equals(e, ext); } + unittest + { + assert(!equalsExt("foo.bar"[], "d")); + assert(equalsExt("foo.bar"[], "bar")); + assert(equalsExt("object.d"[], "d")); + assert(!equalsExt("object"[], "d")); + } + /****************************** * Return !=0 if extensions match. */ From 56a5957848b423d76120d615dfc1b729f9d163a3 Mon Sep 17 00:00:00 2001 From: Geod24 Date: Mon, 27 Aug 2018 23:19:41 +0900 Subject: [PATCH 6/8] Convert FileName.defaultExt to use D slice --- src/dmd/root/filename.d | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/dmd/root/filename.d b/src/dmd/root/filename.d index 3942233592ad..827474a5412e 100644 --- a/src/dmd/root/filename.d +++ b/src/dmd/root/filename.d @@ -480,16 +480,29 @@ nothrow: */ extern (C++) static const(char)* defaultExt(const(char)* name, const(char)* ext) { - const(char)* e = FileName.ext(name); - if (e) // if already has an extension - return mem.xstrdup(name); - size_t len = strlen(name); - size_t extlen = strlen(ext); - char* s = cast(char*)mem.xmalloc(len + 1 + extlen + 1); - memcpy(s, name, len); - s[len] = '.'; - memcpy(s + len + 1, ext, extlen + 1); - return s; + return defaultExt(name.toDString, ext.toDString).ptr; + } + + /// Ditto + extern (D) static const(char)[] defaultExt(const(char)[] name, const(char)[] ext) + { + auto e = FileName.ext(name); + if (e.length) // it already has an extension + return mem.xstrdup(name.ptr)[0 .. name.length]; + const s_length = name.length + 1 + ext.length + 1; + auto s = cast(char*)mem.xmalloc(s_length); + memcpy(s, name.ptr, name.length); + s[name.length] = '.'; + memcpy(s + name.length + 1, ext.ptr, ext.length); + s[s_length - 1] = '\0'; + return s[0 .. s_length - 1]; + } + + unittest + { + assert(defaultExt("/foo/object.d"[], "d") == "/foo/object.d"); + assert(defaultExt("/foo/object"[], "d") == "/foo/object.d"); + assert(defaultExt("/foo/bar.d"[], "o") == "/foo/bar.d"); } /*************************** From c5c07b798c569da0691e0d7c1761b14d5c1476d6 Mon Sep 17 00:00:00 2001 From: Geod24 Date: Mon, 27 Aug 2018 23:26:31 +0900 Subject: [PATCH 7/8] Convert FileName.forceExt to D slice --- src/dmd/root/filename.d | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/dmd/root/filename.d b/src/dmd/root/filename.d index 827474a5412e..af0a6333e54a 100644 --- a/src/dmd/root/filename.d +++ b/src/dmd/root/filename.d @@ -510,20 +510,33 @@ nothrow: */ extern (C++) static const(char)* forceExt(const(char)* name, const(char)* ext) { - const(char)* e = FileName.ext(name); - if (e) // if already has an extension + return forceExt(name.toDString, ext.toDString).ptr; + } + + /// Ditto + extern (D) static const(char)[] forceExt(const(char)[] name, const(char)[] ext) + { + auto e = FileName.ext(name); + if (e.length) // if already has an extension { - size_t len = e - name; - size_t extlen = strlen(ext); - char* s = cast(char*)mem.xmalloc(len + extlen + 1); - memcpy(s, name, len); - memcpy(s + len, ext, extlen + 1); - return s; + const len = name.length - e.length; + char* s = cast(char*)mem.xmalloc(len + ext.length + 1); + memcpy(s, name.ptr, len); + memcpy(s + len, ext.ptr, ext.length); + s[len + ext.length] = '\0'; + return s[0 .. len + ext.length]; } else return defaultExt(name, ext); // doesn't have one } + unittest + { + assert(forceExt("/foo/object.d"[], "d") == "/foo/object.d"); + assert(forceExt("/foo/object"[], "d") == "/foo/object.d"); + assert(forceExt("/foo/bar.d"[], "o") == "/foo/bar.o"); + } + /// Returns: /// `true` if `name`'s extension is `ext` extern (C++) static bool equalsExt(const(char)* name, const(char)* ext) pure From e5e41826fbb8c1582d8746ad4237af6b81b19b08 Mon Sep 17 00:00:00 2001 From: Geod24 Date: Mon, 27 Aug 2018 23:09:47 +0900 Subject: [PATCH 8/8] Convert FileName.removeExt to use D slice --- src/dmd/root/filename.d | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/dmd/root/filename.d b/src/dmd/root/filename.d index af0a6333e54a..f031873d01d3 100644 --- a/src/dmd/root/filename.d +++ b/src/dmd/root/filename.d @@ -183,23 +183,41 @@ nothrow: /******************************** * Return file name without extension. + * + * TODO: + * Once slice are used everywhere and `\0` is not assumed, + * this can be turned into a simple slicing. + * * Params: * str = file name + * * Returns: * mem.xmalloc'd filename with extension removed. */ extern (C++) static const(char)* removeExt(const(char)* str) { - const(char)* e = ext(str); - if (e) + return removeExt(str.toDString).ptr; + } + + /// Ditto + extern (D) static const(char)[] removeExt(const(char)[] str) + { + auto e = ext(str); + if (e.length) { - size_t len = (e - str) - 1; + const len = (str.length - e.length) - 1; // -1 for the dot char* n = cast(char*)mem.xmalloc(len + 1); - memcpy(n, str, len); + memcpy(n, str.ptr, len); n[len] = 0; - return n; + return n[0 .. len]; } - return mem.xstrdup(str); + return mem.xstrdup(str.ptr)[0 .. str.length]; + } + + unittest + { + assert(removeExt("/foo/bar/object.d"[]) == "/foo/bar/object"); + assert(removeExt("/foo/bar/frontend.di"[]) == "/foo/bar/frontend"); } /********************************