digitalmars.D.announce - Some path functions
- Kramer (1010/1010) Jul 30 2006 I have some functions for the path module that I'd like to submit to the...
- Kramer (635/635) Jul 30 2006 Here's the unittests. An excessive amount to be sure, but, hey,
- Bruno Medeiros (7/13) Aug 17 2006 Seems nice (haven't used yet though, maybe in the future, for shell
- Kramer (3/15) Aug 17 2006 Thanks. Hopefully, they're useful. :)
I have some functions for the path module that I'd like to submit to the
general public. I haven't worked on them for about half a year and I
had submitted them to Walter for inclusion into Phobos a while back, but
he's got far more pressing issues (like bug fixes and spec. stability)
to concern himself with.
The list of included functions:
getRoots
isRoot
containsRoot
normPath // normalize a path; similar to the Python version
// http://docs.python.org/lib/module-os.path.html
isNormPath
normCase // normalize the case
normSep // normalize the separators for the given os
join // variadic join
absPath // includes a private isAbs because the one in std.path doesn't
seem to be working
expandPath // similar to the Ruby version
// http://www.rubycentral.com/ref/ref_c_file.html#expand_path
I offer the code free to anyone; use it as you may, it's public domain.
I hope it works, but offer no assurances on it's quality and am not
responsible for it's use in other code.
It compiles clean under DMD 0.163 on Windows, but I haven't tested it on
Linux since I wrote it -- I no longer have access to a Linux box. The
functions use an internal isAbs function because when I was writing the
code I found the one in Phobos to not be accurate. I'm probably wrong
on that front, so to get the Phobos isAbs functionality, remove the
internal one (the internal one returns a bool instead of an int, so any
compares will need to be modified).
Hopefully someone will find it useful, but in the end, I just wanted to
do my small share to contribute to this fantastic language.
Walter, keep up the good work on this language. But I have to say,
honestly, to the community, keep up the good work and motivation. I've
never come across a more intelligent and dedicated langauge community.
And friendly by the way. It's always a pleasure reading the newsgroups.
Onward, upward and D-ward!
-Kramer
P.S. - I'm having some trouble attaching the code so I'm just pasting it
in this message. Formatting will be screwy I'm sure, but I'm not sure
how else to post. I think my file is too large to send, so I'm leaving
out the unittests in this message and will past them in another.
/**
* Author: Joe Zuccarello
* Date: February 2006
*
* By the author's permission, this code is considered in the public
domain for modification and
* redistribution at will.
*/
private import std.string,
std.path,
std.file,
std.regexp,
std.utf,
std.stdarg,
std.format;
version(Windows) private import std.c.windows.windows;
version(Windows)
{
extern(Windows)
{
export
{
DWORD GetLogicalDriveStringsA(DWORD, LPTSTR);
DWORD GetLogicalDriveStringsW(DWORD, LPWSTR);
}
}
}
private static const char[] wSep = r"\",
lSep = "/",
rSeps = "[\\\\/]"; // For regexp use
void main() {}
/**
* Returns all roots for the system.
*
* This will return all the roots that are know by the system.
*
* For Windows, it will be the drives that are available.
* For Linux, it will always return root "/".
*
* Note, this function uses the Windows API to retrieve the roots. If
is ANSI characters are being
* used, getRoots will attemp to convert it to UTF8. If the UTF8 code
throws a UTF exception,
* that exception will not be caught and will be propogated to the
caller code.
*
* Authors: Joe Zuccarello
*
* Date: February 14, 2006
*
* Returns: All roots for the system.
*
* Throws: (Windows) UtfException on conversion error from ANSI to
UTF-8 if the OS is using ANSI.
*
* Version:
*
* License: Public domain.
*
* Examples:
* ---------
* version(Windows)
* {
* // Assume roots "A:\", "C:\" and "D:\" exist
* getRoots() => "A:\", "C:\", "D:\"
* }
* version(linux)
* {
* getRoots() => "/"
* }
* ---------
*/
char[][] getRoots()
{
char[][] rtnBuffer;
version(Windows)
{
DWORD bufferLen = 50,
rtnVal;
char[] buffer;
// Unicode
void getDrivesW()
{
wchar[] wBuffer;
wBuffer.length = bufferLen;
rtnVal = GetLogicalDriveStringsW(bufferLen, wBuffer);
buffer = std.utf.toUTF8(wBuffer);
}
// ANSI
void getDrivesA()
{
char* tmpBuf = std.windows.charset.toMBSz(buffer);
rtnVal = GetLogicalDriveStringsA(bufferLen, tmpBuf);
buffer = std.windows.charset.fromMBSz(tmpBuf);
}
// Set initial buffer size
buffer.length = bufferLen;
if (useWfuncs)
{
getDrivesW();
}
else
{
getDrivesA();
}
while (rtnVal > bufferLen)
{
bufferLen = rtnVal;
buffer.length = bufferLen;
if (useWfuncs)
{
getDrivesW();
}
else
{
getDrivesA();
}
}
rtnBuffer.length = buffer.length;
int j = 0;
for (int i, nullCnt = 0; i < buffer.length && nullCnt < 2; i++)
{
if (buffer[i..(i + 1)] != "\0")
{
rtnBuffer[j] ~= buffer[i..(i + 1)];
nullCnt = 0;
}
else
{
nullCnt++;
j++;
}
}
rtnBuffer.length = j - 1;
return rtnBuffer.dup;
}
else version(linux)
{
rtnBuffer ~= "/";
return rtnBuffer.dup;
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
}
/**
* Returns true/false whether a path is a root of the system.
*
* This can be used to test a path to see if it's a root of the system.
*
* Authors: Joe Zuccarello
*
* Date: February 14, 2006
*
* Returns: true/false whether a path is a root of the system.
*
* Version:
*
* License: Public domain.
*
* Examples:
* ---------
* version(Windows)
* {
* // Assume on Windows, c:\ exists
* isRoot(r"c:\") => true
* }
* version(linux)
* {
* isRoot("/") => true
* }
* ---------
*/
bool isRoot(char[] path, bool caseSensitive = false)
{
char[][] roots = getRoots();
foreach (char[] x; roots)
{
if (caseSensitive == true)
{
if (x == path)
{
return true;
}
}
else
{
if (std.string.tolower(x) == std.string.tolower(path))
{
return true;
}
}
}
return false;
}
/**
* Returns true/false whether a path contains a root of the system.
*
* This can be used to test a path, to determine if it starts with a
system root.
*
* Authors: Joe Zuccarello
*
* Date: February 15, 2006
*
* Returns: true/false whether a path starts with a system root.
*
* Version:
*
* License: Public domain.
*
* Examples:
* ---------
* version(Windows)
* {
* // Assume on Windows, c:\ exists
* containsRoot(r"c:\directory\file") => true
* containsRoot(r"\directory\file") => false
* }
* version(linux)
* {
* containsRoot("/usr/d/src") => true
* containsRoot("../d/src") => false
* containsRoot("\d/src") => false
* }
* ---------
*/
bool containsRoot(char[] path, bool caseSensitive = false)
{
char[][] roots = getRoots();
foreach (char[] x; roots)
{
if (caseSensitive == true)
{
if (std.string.find(path, x) == 0)
{
return true;
}
}
else
{
if (std.string.ifind(path, x) == 0)
{
return true;
}
}
}
return false;
}
/**
* Test whether a path is normalized.
*
* Use this to test whether a path is normalized.
*
* Note: This function does not handle UNC paths.
*
* Authors: Joe Zuccarello
*
* Date: February 15, 2006
*
* Returns: true/false whether a path is normalized.
*
* Version:
*
* License: Public domain.
*
* Examples:
* ---------
* version(Windows)
* {
* isNormPath(r"directory1\..\directory2\file\.") => false
* // This one returns true, because there's no parent directory to
collapse to.
* isNormPath(r"..\directory\file") => true
* }
* version(linux)
* {
* isNormPath("/dir/../file") => false
* isNormPath("/file") => true
* }
* ---------
*/
bool isNormPath(char[] path)
{
RegExp re;
version(Windows)
{
// Special cases
if (path == "." || path == ".." || (path == r"\" || path == "/") ||
std.regexp.find(path, "^\\.\\." ~ "(" ~ rSeps ~ "\\.\\.)+") !=
-1 ||
std.regexp.find(path, "^[a-zA-Z]*:" ~ rSeps ~ "$") != -1)
{
return true;
}
else
{
// Look for the following. If found, then this is not a
normalized path
if (std.regexp.find(path, rSeps ~ "$") != -1 ||
std.regexp.find(path, rSeps ~ "\\.\\." ~ "(" ~ rSeps ~
"|$)") != -1 ||
std.regexp.find(path, rSeps ~ "\\." ~ "(" ~ rSeps ~ "|$)")
!= -1 ||
std.regexp.find(path, "^\\." ~ rSeps) != -1 ||
std.regexp.find(path, rSeps ~ "{2,}") != -1)
{
return false;
}
else
{
return true;
}
}
}
else version(linux)
{
// Special cases
if (path == "." || path == ".." || (path == r"\" || path == "/") ||
std.regexp.find(path, "^\\.\\." ~ "(" ~ rSeps ~ "\\.\\.)+") != -1)
{
return true;
}
else
{
// Look for the following. If found, then this is not a
normalized path
if (std.regexp.find(path, lSep ~ "$") != -1 ||
std.regexp.find(path, lSep ~ "\\.\\." ~ "(" ~ lSep ~ "|$)")
!= -1 ||
std.regexp.find(path, lSep ~ "\\." ~ "(" ~ lSep ~ "|$)") !=
-1 ||
std.regexp.find(path, "^\\." ~ lSep) != -1 ||
std.regexp.find(path, lSep ~ "{2,}") != -1)
{
return false;
}
else
{
return true;
}
}
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
}
/**
* Normalizes a path.
*
* This will normalize a path by collapsing redundant separators and
parent/current directory
* references. It will also remove any trailing separators and
normalize separators as appropriate
* for the OS.
*
* Inspired by the Python v2.4.2 implementation.
*
* Note: This function does not handle UNC paths.
*
* Authors: Joe Zuccarello
*
* Date: February 15, 2006
*
* Returns: A normalized path.
*
* Version:
*
* License: Public domain.
*
* Examples:
* ---------
* normPath("/dir1/../dir2/./file/") => "/dir2/file"
* normPath("/dir..../file/./") => "/dir..../file"
* ---------
*/
char[] normPath(char[] path)
out(result)
{
assert(isNormPath(result));
}
body
{
int pcIdx, pcIdx2;
char[][] pathComps; // path components after splitting
char[] result, drive;
// Normalize the separators for the os
path = normSep(path);
// Sanity check. No need to process a separator, curdir or pardir
reference.
if (path != sep && path != curdir && path != pardir)
{
// Remove the drive from the path
version(Windows)
{
int idx = std.string.find(path, ":");
drive ~= idx != -1 ? path[0..(idx + 1)] : "";
if (idx != -1)
{
if ((idx + 1) < path.length)
{
path = path[(idx + 1)..$];
}
else
{
path = "";
}
}
}
// Remove repeating separators
path = std.string.squeeze(path, sep);
// If there's an initial separator even after a drive, save it off
if (path != "")
{
if (path[0..1] == sep)
{
drive ~= sep;
}
}
// Split the path components
pathComps = std.string.split(path, sep);
while (pcIdx < pathComps.length)
{
// Current directory
if (pathComps[pcIdx] == curdir)
{
if (pathComps.length == 1)
{
pathComps.length = 0;
}
else if (pathComps.length > 1)
{
// At the beginning
if (pcIdx == 0)
{
pathComps = pathComps[1..$];
}
// At the end
else if ((pcIdx + 1) == pathComps.length)
{
pathComps = pathComps[0..pcIdx];
}
// In the middle
else
{
pathComps = pathComps[0..pcIdx] ~
pathComps[(pcIdx + 1)..$];
}
}
}
// Parent directory reference
else if (pathComps[pcIdx] == pardir)
{
if (pathComps.length == 1)
{
pcIdx++;
}
else if (pathComps.length > 1)
{
// At the beginning
if (pcIdx == 0)
{
// We don't know what to do with this, so move on
pcIdx++;
}
// Found a reference but there was a separator
before it. Need
// to remove this reference.
else if (pcIdx == 1 && pathComps[(pcIdx - 1)] == "")
{
// Delete the reference
if ((pcIdx + 1) < pathComps.length)
{
pathComps = pathComps[0..pcIdx] ~
pathComps[(pcIdx + 1)..$];
pcIdx--;
}
else
{
pathComps = pathComps[0..pcIdx];
}
}
else
{
if (pathComps[(pcIdx - 1)] != pardir)
{
if ((pcIdx + 1) < pathComps.length)
{
// Delete the reference and the
preceding entry
pathComps = pathComps[0..(pcIdx - 1)] ~
pathComps[(pcIdx + 1)..$];
pcIdx--;
}
// End of line
else
{
pathComps = pathComps[0..(pcIdx - 1)];
}
}
else
{
pcIdx++;
}
}
}
}
// Something else
else
{
pcIdx++;
}
}
// Delete any blank chunks out of the array for joining later
for (int i = 0; i < pathComps.length; i++)
{
if (pathComps[i] == "")
{
if (pathComps.length == 1)
{
pathComps.length = 0;
}
else if (pathComps.length > 1)
{
// At the beginning
if (i == 0)
{
pathComps = pathComps[1..$];
}
// At the end
else if ((i + 1) == pathComps.length)
{
pathComps = pathComps[0..i];
}
// In the middle. This should already have been
taken care of from the logic near
// the top of this function from using the squeeze
and then split, there shouldn't be
// any blank chunks in the middle.
}
}
}
result = std.string.join(pathComps, sep);
}
// Path was either a separator, curdir or pardir reference
else
{
result = path;
}
if (result == "" && drive == "")
{
result = curdir;
}
else
{
result = drive ~ result;
}
return result.dup;
}
/**
* Normalize the case and separators of a path.
*
* This will normalize the case for a path depending on the operating
system in use. For case
* -insensitive os's (such as Windows), the path will be lower-cased.
For case sensitive os's (such
* as Linux), the path case will not be changed. On Windows, forward
slashes will be converted to
* backward slashes and on Linux, backward slashes will be converted to
forward slashes.
*
* Authors: Joe Zuccarello
*
* Date: February 15, 2006
*
* Returns: Normalized case and separators for a path.
*
* Version:
*
* License: Public domain.
*
* Examples:
* ---------
* version(Windows)
* {
* normCase(r"C:\directory1\Subdirectory/FILE) =>
"c:\directory1\subdirectory\file"
* }
* version(linux)
* {
* normCase(r"\usr/src\Path.d") => "\usr/src\Path.d"
* }
* ---------
*/
char[] normCase(char[] path)
{
version(Windows)
{
// Take care of the case
path = std.string.tolower(path);
}
path = normSep(path);
return path.dup;
}
/**
*
* Normalizes the separators in a path.
*
* Use this to normalize separators as appropriate for the operating
system in use. On Windows,
* forward slashes * will be converted to backward slashes. On Linux,
the path will just be
* returned.
*
* Authors: Joe Zuccarello
*
* Date: February 15, 2006
*
* Returns: Normalized separators for a path.
*
* Version:
*
* License: Public domain.
*
* Examples:
* ---------
* version(Windows)
* {
* normSep(r"c:/directory\file") => "c:\directory\file"
* }
* version(linux)
* {
* normSep(r"/dir1\dir2\dir3/file") => "/dir1\dir2\dir3/file"
* }
* ---------
*/
char[] normSep(char[] path)
{
version(Windows)
{
// Convert separators
if (std.regexp.find(path, lSep) != -1)
{
path = std.string.replace(path, lSep, wSep);
return path.dup;
}
else
{
return path;
}
}
else version(linux)
{
return path;
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
}
/**
* Joins an arbitrary number of paths together, using std.path.join as
the main joining component.
*
* This will take an arbitrary number of paths and join them by passing
them to std.path.join to do
* the actual joining. *** Join rules follow that of std.path.join ***
*
* Note, this function may attempt to convert non-UTF8 characters to
UTF8. If the UTF8 code throws
* a UTF exception, that exception will not be caught and will be
propogated to the caller code.
*
* Authors: Joe Zuccarello
*
* Date: February 15, 2006
*
* Returns: A path joined of one or more separate paths.
*
* Throws: UtfException on error from conversion of wchar or dchar
parameters.
*
* Version:
*
* License: Public domain.
*
* Examples:
* ---------
* join(r"\dir1", "dir2", "dir3/file") => "\dir1\dir2\dir3/file"
* ---------
*/
char[] join(...)
{
char[] pathX, rtnPath;
char[] toStringW(wchar c)
{
wchar[] result;
result.length = 1;
result[0] = c;
return std.utf.toUTF8(result);
}
char[] toStringD(dchar c)
{
dchar[] result;
result.length = 1;
result[0] = c;
return std.utf.toUTF8(result);
}
for (int i = 0; i < _arguments.length; i++)
{
if (_arguments[i] == typeid(char[]))
{
pathX = va_arg!(char[])(_argptr);
}
else if (_arguments[i] == typeid(wchar[]))
{
pathX = std.string.toUTF8(va_arg!(wchar[])(_argptr));
}
else if (_arguments[i] == typeid(dchar[]))
{
pathX = std.string.toUTF8(va_arg!(dchar[])(_argptr));
}
else if (_arguments[i] == typeid(char))
{
pathX = std.string.toString(va_arg!(char)(_argptr));
}
else if (_arguments[i] == typeid(wchar))
{
pathX = toStringW(va_arg!(wchar)(_argptr));
}
else if (_arguments[i] == typeid(dchar))
{
pathX = toStringD(va_arg!(dchar)(_argptr));
}
if (pathX != "")
{
rtnPath = std.path.join(rtnPath, pathX);
pathX = "";
}
}
return rtnPath.dup;
}
/**
* Returns a normalized absolutized path.
*
* If the path is not absolute, it will be joined with the current
working directory. If it is an
* absolute path, nothing will be joined with it. In either case, the
path will also be checked to
* see if it is normalized. If it's not, it will be normalized.
*
* Note: This function does not handle UNC paths.
*
* Authors: Joe Zuccarello
*
* Date: February 15, 2006
*
* Returns: A normalized absolutized path.
*
* Version:
*
* License: Public domain.
*
* Examples:
* ---------
* version(Windows)
* {
* // Assume c:\ is the current working directory
* absPath(r"file") => "c:\file"
* absPath(r"c:\d/src\project") => "c:\d\src\project"
* absPath(r".\dir\file\..\dir2\file2") => "c:\dir\dir2\file2"
* }
* version(linux)
* {
* // Assume /usr is the current working directory
* absPath("d/bin") => "/usr/d/bin"
* absPath("/d/lib") => "/d/lib"
* absPath("d/src/../file") => "/usr/d/file"
* }
* ---------
*/
char[] absPath(char[] path)
out(result)
{
assert(isNormPath(result));
}
body
{
bool changed;
version(Windows)
{
// Path is not absolute
//if (std.regexp.find(path, "^[a-zA-Z]*:\\\\") == -1)
if (isAbs(path) == false)
{
path = std.path.join(getcwd(), path);
changed = true;
}
}
else version(linux)
{
// Path is not absolute
//if (path[0..1] != r"\" && path[0..1] != "/")
if (isAbs(path) == false)
{
path = std.path.join(getcwd(), path);
changed = true;
}
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
// Normalize the path
if (isNormPath(path) == false)
{
path = normPath(path);
changed = true;
}
if (changed == true)
{
return path.dup;
}
else
{
return path;
}
}
private bool isAbs(char[] path)
{
version(Windows)
{
if (std.regexp.find(path, "^[a-zA-Z]*:\\\\") != -1)
{
return true;
}
else
{
return false;
}
}
else version(linux)
{
if (path[0..1] == "/")
{
return true;
}
else
{
return false;
}
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
}
/**
* Expands a path into a normalized absolutized path, with a optional
reference directory to use
* with relative paths.
*
* This will take a path and expand it into a normalized absolutized
version of itself. An optional
* reference directory can be provided as well. If the path passed in
is relative, the reference
* directory will be used to precede the path. If the reference
directory is a relative directory,
* the reference directory and the path will be appended to the current
working directory.
*
* Note: This function does not handle UNC paths.
*
* Authors: Joe Zuccarello
*
* Date: February 15, 2006
*
* Returns: A normalized absolutized path.
*
* Version:
*
* License: Public domain.
*
* Examples:
* ---------
* version(Windows)
* {
* // Assume c:\ is the current working directory
* expandPath("file") => "c:\file"
* expandPath(r"\dir\file") => "c:\dir\file"
* expandPath("file", r"\dir") => "c:\dir\file"
* }
* version(linux)
* {
* // Assume /usr is the current working directory
* expandPath("file") => "/usr/file"
* expandPath(r"/dir/file") => "/usr/dir/file"
* expandPath("file", "/dir") => "/usr/dir/file"
* }
* ---------
*/
char[] expandPath(char[] path, char[] dir = "")
{
char[] result;
if (path != "")
{
// Path is absolute; ditch the dir and return this after
normalizing.
if (isAbs(path) == true)
{
result = normPath(path);
}
// Path is not absolute
else
{
if (dir != "")
{
// Check if dir is absolute
if (isAbs(dir) == true)
{
result = normPath(dir ~ sep ~ path);
}
// Dir is not absolute, but it is a directory (at least
that's
// what the caller is telling us.
else
{
result = normPath(getcwd() ~ sep ~ dir ~ sep ~ path);
}
}
// Dir is empty and path is not absolute
else
{
result = normPath(getcwd() ~ sep ~ path);
}
}
}
// Path is empty, check dir
else
{
if (dir != "")
{
// Check if dir is absolute
if (isAbs(dir) == true)
{
result = normPath(dir);
}
else
{
result = normPath(getcwd() ~ sep ~ dir);
}
}
// Path and dir are empty
else
{
result = "";
}
}
return result.dup;
}
Jul 30 2006
Here's the unittests. An excessive amount to be sure, but, hey,
sometimes overly verifing your code can be fun. :)
// isRoot
unittest
{
version(Windows)
{
// Valid roots
assert(isRoot(getDrive(getcwd()) ~ sep));
assert(isRoot(std.string.toupper(getDrive(getcwd()) ~ sep), true));
// Invalid roots
char[][] roots = getRoots();
char[] lastRoot = roots[($ - 1)];
char[] succRoot = std.string.succ(lastRoot[0..($ - 2)]) ~
lastRoot[($ - 2)..$];
assert(!isRoot(succRoot));
assert(!isRoot(std.string.tolower(getDrive(getcwd()) ~ sep), true));
}
else version(linux)
{
// Valid roots
assert(isRoot("/"));
assert(isRoot(getRoots()[0]));
// Invalid roots
assert(!isRoot("../"));
assert(!isRoot(r"\"));
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
}
// containsRoot
unittest
{
version(Windows)
{
// Valid roots
assert(containsRoot(getcwd()));
assert(containsRoot(getDrive(getcwd()) ~ sep));
assert(containsRoot(std.string.toupper(getcwd()), true));
// Invalid roots
int idx = std.string.find(getcwd(), getDrive(getcwd()));
assert(!containsRoot(getcwd()[idx..(getDrive(getcwd()).length)]));
assert(!containsRoot(std.string.tolower(getcwd()), true));
assert(!containsRoot(std.string.tolower(getDrive(getcwd()) ~ sep),
true));
assert(!containsRoot(r"\directory\file"));
}
else version(linux)
{
// Valid roots
assert(containsRoot("/usr/d/src"));
// Invalid roots
assert(!containsRoot("../d/src"));
assert(!containsRoot(r"\d/src"));
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
}
// isNormPath
unittest
{
version(Windows)
{
assert(!isNormPath(r" .\"));
assert(!isNormPath(r".\"));
assert(!isNormPath(r"\."));
assert(!isNormPath(r"\.\"));
assert(!isNormPath(r"..\"));
assert(!isNormPath(r"\.."));
assert(!isNormPath(r"\..\"));
assert(!isNormPath(r"\\"));
}
else version(linux)
{
assert(isNormPath(r" .\"));
assert(isNormPath(r".\"));
assert(isNormPath(r"\."));
assert(isNormPath(r"\.\"));
assert(isNormPath(r"..\"));
assert(isNormPath(r"\.."));
assert(isNormPath(r"\..\"));
assert(isNormPath(r"\\"));
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
// These patterns are not normalized paths
assert(!isNormPath("//"));
assert(!isNormPath(" ./"));
assert(!isNormPath("./"));
assert(!isNormPath("/."));
assert(!isNormPath("/./"));
assert(!isNormPath("../"));
assert(!isNormPath("/.."));
assert(!isNormPath("/../"));
assert(!isNormPath(r"\/"));
// These patterns are normalized paths
assert(isNormPath(""));
assert(isNormPath(" "));
assert(isNormPath(" "));
assert(isNormPath(" a b c"));
assert(isNormPath("b"));
assert(isNormPath("."));
assert(isNormPath(".."));
assert(isNormPath(r"\"));
assert(isNormPath("/"));
assert(isNormPath(r"..\.."));
assert(isNormPath("../.."));
// Now test the patterns that are part of the normPath unittest,
duh duh dun...
assert(isNormPath(normPath("")));
assert(isNormPath(normPath(" ")));
assert(isNormPath(normPath(" ")));
assert(isNormPath(normPath(".")));
assert(isNormPath(normPath("..")));
assert(isNormPath(normPath(r"\")));
assert(isNormPath(normPath("/")));
assert(isNormPath(normPath("/.")));
assert(isNormPath(normPath("./")));
assert(isNormPath(normPath(r"\.")));
assert(isNormPath(normPath(r".\")));
assert(isNormPath(normPath(r".\dir1\dir2\file")));
assert(isNormPath(normPath("./dir1/dir2/file")));
assert(isNormPath(normPath(r"dir1\dir2\file\.")));
assert(isNormPath(normPath("dir1/dir2/file/.")));
assert(isNormPath(normPath(r"\dir1\dir2\file\.")));
assert(isNormPath(normPath("/dir1/dir2/file/.")));
assert(isNormPath(normPath(r".\dir1\dir2\file\.")));
assert(isNormPath(normPath("./dir1/dir2/file/.")));
assert(isNormPath(normPath(r".\.\dir1\dir2\file\.")));
assert(isNormPath(normPath("././dir1/dir2/file/.")));
assert(isNormPath(normPath(r".\.\dir1\dir2\file\.\.")));
assert(isNormPath(normPath("././dir1/dir2/file/./.")));
assert(isNormPath(normPath(r"dir1\.\dir2")));
assert(isNormPath(normPath("dir1/./dir2")));
assert(isNormPath(normPath(r"dir1\.\.\.\dir2\.\file")));
assert(isNormPath(normPath("dir1/./././dir2/./file")));
assert(isNormPath(normPath(r".\.")));
assert(isNormPath(normPath("./.")));
assert(isNormPath(normPath(r"\.\")));
assert(isNormPath(normPath("/./")));
assert(isNormPath(normPath(r"\.\.\.")));
assert(isNormPath(normPath("/././.")));
assert(isNormPath(normPath(r".\.\.\")));
assert(isNormPath(normPath("./././")));
assert(isNormPath(normPath("dir")));
assert(isNormPath(normPath("c:")));
assert(isNormPath(normPath(r"c:\..")));
assert(isNormPath(normPath("c:/..")));
assert(isNormPath(normPath(r"\dir")));
assert(isNormPath(normPath("/dir")));
assert(isNormPath(normPath(r"\dir1\file")));
assert(isNormPath(normPath("/dir1/file")));
assert(isNormPath(normPath(r"\dir1\file\")));
assert(isNormPath(normPath("/dir1/file/")));
assert(isNormPath(normPath(r"\dir1\file\..")));
assert(isNormPath(normPath("/dir1/file/..")));
assert(isNormPath(normPath(r"\dir1\dir2\..\file")));
assert(isNormPath(normPath("/dir1/dir2/../file")));
assert(isNormPath(normPath(r"\dir1\file..")));
assert(isNormPath(normPath("/dir1/file..")));
assert(isNormPath(normPath(r"\dir1\file\..\..")));
assert(isNormPath(normPath("/dir1/file/../..")));
assert(isNormPath(normPath("c:..file")));
assert(isNormPath(normPath(r"c:\..\dir1\..\file")));
assert(isNormPath(normPath("c:/../dir1/../file")));
assert(isNormPath(normPath(r"c:..file\dir1")));
assert(isNormPath(normPath("c:..file/dir1")));
assert(isNormPath(normPath(r"c:..file\dir1\..")));
assert(isNormPath(normPath("c:..file/dir1/..")));
assert(isNormPath(normPath(".")));
assert(isNormPath(normPath(r"c:\")));
assert(isNormPath(normPath("c:/")));
assert(isNormPath(normPath(r"c:\dir1\.\")));
assert(isNormPath(normPath("c:/dir1/./")));
assert(isNormPath(normPath(r"c:\dir1\.\file")));
assert(isNormPath(normPath("c:/dir1/./file")));
assert(isNormPath(normPath(r"c:\dir1\.\file\")));
assert(isNormPath(normPath("c:/dir1/./file/")));
assert(isNormPath(normPath(r"c:\dir1\..\file")));
assert(isNormPath(normPath("c:/dir1/../file")));
assert(isNormPath(normPath(r"c:\dir1\..\file\")));
assert(isNormPath(normPath("c:/dir1/../file/")));
assert(isNormPath(normPath(r"c:\dir1\..\file\.")));
assert(isNormPath(normPath("c:/dir1/../file/.")));
assert(isNormPath(normPath(r"c:\dir1\..\file\.\")));
assert(isNormPath(normPath("c:/dir1/../file/./")));
assert(isNormPath(normPath(r"c:\dir1\..\file\..")));
assert(isNormPath(normPath("c:/dir1/../file/..")));
assert(isNormPath(normPath(r"\\\dir1\file")));
assert(isNormPath(normPath("///dir1/file")));
assert(isNormPath(normPath(r"\\\dir1\..\dir2\file")));
assert(isNormPath(normPath("///dir1/../dir2/file")));
assert(isNormPath(normPath(r"\\\file")));
assert(isNormPath(normPath("///file")));
assert(isNormPath(normPath(r"..\..")));
assert(isNormPath(normPath("../..")));
assert(isNormPath(normPath(r"..\\\..")));
assert(isNormPath(normPath("..///..")));
assert(isNormPath(normPath(r"..\")));
assert(isNormPath(normPath("../")));
assert(isNormPath(normPath(r"..\\\\")));
assert(isNormPath(normPath("..////")));
assert(isNormPath(normPath(r".\")));
assert(isNormPath(normPath("./")));
assert(isNormPath(normPath(r"\.\file")));
assert(isNormPath(normPath("/./file")));
assert(isNormPath(normPath("c:" ~ sep ~ "dir1" ~ sep ~ "." ~ sep)));
assert(isNormPath(normPath("c:" ~ sep ~ "dir1" ~ sep ~ "." ~ sep ~
"file")));
assert(isNormPath(normPath("c:" ~ sep ~ "dir1" ~ sep ~ "." ~ sep ~
"file" ~ sep)));
assert(isNormPath(normPath("c:" ~ sep ~ "dir1" ~ sep ~ ".." ~ sep ~
"file")));
assert(isNormPath(normPath("c:" ~ sep ~ "dir1" ~ sep ~ ".." ~ sep ~
"file" ~ sep)));
assert(isNormPath(normPath("c:" ~ sep ~ "dir1" ~ sep ~ ".." ~ sep ~
"file" ~ sep ~ ".")));
assert(isNormPath(normPath("c:" ~ sep ~ "dir1" ~ sep ~ ".." ~ sep ~
"file" ~ sep ~ "." ~ sep)));
assert(isNormPath(normPath("c:" ~ sep ~ "dir1" ~ sep ~ ".." ~ sep ~
"file" ~ sep ~ "..")));
assert(isNormPath(normPath(sep ~ sep ~ sep ~ "dir1" ~ sep ~ "file")));
assert(isNormPath(normPath(sep ~ sep ~ sep ~ "dir1" ~ sep ~ ".." ~
sep ~ "dir2" ~ sep ~ "file")));
assert(isNormPath(normPath(sep ~ sep ~ sep ~ "file")));
assert(isNormPath(normPath(".." ~ sep ~ "..")));
assert(isNormPath(normPath(".." ~ sep ~ sep ~ sep ~ "..")));
assert(isNormPath(normPath(".." ~ sep)));
assert(isNormPath(normPath(".." ~ sep ~ sep ~ sep ~ sep)));
assert(isNormPath(normPath("." ~ sep)));
assert(isNormPath(normPath(sep ~ "." ~ sep ~ "file")));
assert(isNormPath(normPath(r"~\dir")));
assert(isNormPath(normPath("~/dir")));
assert(isNormPath(normPath(sep ~ "..")));
assert(isNormPath(normPath(sep ~ ".." ~ sep)));
assert(isNormPath(normPath(sep ~ ".." ~ sep ~ "dir")));
assert(isNormPath(normPath(sep ~ "..file")));
assert(isNormPath(normPath(sep ~ ".file")));
assert(isNormPath(normPath(".file")));
assert(isNormPath(normPath("file.")));
assert(isNormPath(normPath("file.file" ~ sep ~ "." ~ sep ~ "dir1" ~
sep ~ "dir2" ~ sep ~ "..")));
assert(isNormPath(normPath("file$.")));
}
// normPath
unittest
{
version(Windows)
{
assert(normPath("c:") == "c:");
assert(normPath("c:" ~ sep ~ "..") == r"c:" ~ sep);
assert(normPath("c:" ~ sep ~ ".." ~ sep ~ "dir1" ~ sep ~ ".." ~ sep
~ "file") == "c:" ~ sep ~ "file");
assert(normPath("c:" ~ sep) == "c:" ~ sep);
assert(normPath("c:" ~ sep ~ "dir1" ~ sep ~ "." ~ sep) == "c:" ~
sep ~ "dir1");
assert(normPath("c:" ~ sep ~ "dir1" ~ sep ~ "." ~ sep ~ "file") ==
"c:" ~ sep ~ "dir1" ~ sep ~ "file");
assert(normPath("c:" ~ sep ~ "dir1" ~ sep ~ "." ~ sep ~ "file" ~
sep) == "c:" ~ sep ~ "dir1" ~ sep ~ "file");
assert(normPath("c:" ~ sep ~ "dir1" ~ sep ~ ".." ~ sep ~ "file") ==
"c:" ~ sep ~ "file");
assert(normPath("c:" ~ sep ~ "dir1" ~ sep ~ ".." ~ sep ~ "file" ~
sep) == "c:" ~ sep ~ "file");
assert(normPath("c:" ~ sep ~ "dir1" ~ sep ~ ".." ~ sep ~ "file" ~
sep ~ ".") == "c:" ~ sep ~ "file");
assert(normPath("c:" ~ sep ~ "dir1" ~ sep ~ ".." ~ sep ~ "file" ~
sep ~ "." ~ sep) == "c:" ~ sep ~ "file");
assert(normPath("c:" ~ sep ~ "dir1" ~ sep ~ ".." ~ sep ~ "file" ~
sep ~ "..") == "c:" ~ sep);
assert(normPath(r"\\/dir1////\\dir2//..\\\\file/./") == sep ~
"dir1" ~ sep ~ "file");
}
else version(linux)
{
assert(normPath("c:/../file") == "file");
assert(normPath(r"c:\..\file") == r"c:\..\file");
assert(normPath("~/dir") == "~/dir");
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
assert(normPath("") == ".");
assert(normPath(r" ./") == r" .");
assert(normPath(" ") == " ");
assert(normPath(" ") == " ");
assert(normPath(".") == ".");
assert(normPath("..") == "..");
assert(normPath(sep) == sep);
assert(normPath(sep ~ curdir) == sep);
assert(normPath(curdir ~ sep) == curdir);
assert(normPath(curdir ~ sep ~ "dir1" ~ sep ~ "dir2" ~ sep ~
"file") == "dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(normPath("dir1" ~ sep ~ "dir2" ~ sep ~ "file" ~ sep ~
curdir) == "dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(normPath(sep ~ "dir1" ~ sep ~ "dir2" ~ sep ~ "file" ~ sep ~
curdir) == sep ~ "dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(normPath(curdir ~ sep ~ "dir1" ~ sep ~ "dir2" ~ sep ~ "file"
~ sep ~ curdir) == "dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(normPath(curdir ~ sep ~ curdir ~ sep ~ "dir1" ~ sep ~ "dir2"
~ sep ~ "file" ~ sep ~ curdir) == "dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(normPath(curdir ~ sep ~ curdir ~ sep ~ "dir1" ~ sep ~ "dir2"
~ sep ~ "file" ~ sep ~ curdir ~ sep ~ curdir) == "dir1" ~ sep ~ "dir2" ~
sep ~ "file");
assert(normPath("dir1" ~ sep ~ curdir ~ sep ~ "dir2") == "dir1" ~
sep ~ "dir2");
assert(normPath("dir1" ~ sep ~ curdir ~ sep ~ curdir ~ sep ~ curdir
~ sep ~ "dir2" ~ sep ~ curdir ~ sep ~ "file") == "dir1" ~ sep ~ "dir2" ~
sep ~ "file");
assert(normPath(curdir ~ sep ~ curdir) == curdir);
assert(normPath(sep ~ curdir ~ sep) == sep);
assert(normPath(sep ~ curdir ~ sep ~ curdir ~ sep ~ curdir) == sep);
assert(normPath(curdir ~ sep ~ curdir ~ sep ~ curdir ~ sep) == curdir);
assert(normPath("dir") == "dir");
assert(normPath(sep ~ "dir") == sep ~ "dir");
assert(normPath(sep ~ "dir1" ~ sep ~ "file") == sep ~ "dir1" ~ sep
~ "file");
assert(normPath(sep ~ "dir1" ~ sep ~ "file" ~ sep) == sep ~ "dir1"
~ sep ~ "file");
assert(normPath(sep ~ "dir1" ~ sep ~ "file" ~ sep ~ "..") == sep ~
"dir1");
assert(normPath(sep ~ "dir1" ~ sep ~ "dir2" ~ sep ~ ".." ~ sep ~
"file") == sep ~ "dir1" ~ sep ~ "file");
assert(normPath(sep ~ "dir1" ~ sep ~ "file..") == sep ~ "dir1" ~
sep ~ "file..");
assert(normPath(sep ~ "dir1" ~ sep ~ "file" ~ sep ~ ".." ~ sep ~
"..") == sep);
assert(normPath("c:..file") == "c:..file");
assert(normPath("c:..file" ~ sep ~ "dir1") == "c:..file" ~ sep ~
"dir1");
assert(normPath("c:..file" ~ sep ~ "dir1" ~ sep ~ "..") == "c:..file");
assert(normPath(sep ~ sep ~ sep ~ "dir1" ~ sep ~ "file") == sep ~
"dir1" ~ sep ~ "file");
assert(normPath(sep ~ sep ~ sep ~ "dir1" ~ sep ~ ".." ~ sep ~
"dir2" ~ sep ~ "file") == sep ~ "dir2" ~ sep ~ "file");
assert(normPath(sep ~ sep ~ sep ~ "file") == sep ~ "file");
assert(normPath(".." ~ sep ~ "..") == ".." ~ sep ~ "..");
assert(normPath(".." ~ sep ~ sep ~ sep ~ "..") == ".." ~ sep ~ "..");
assert(normPath(".." ~ sep) == "..");
assert(normPath(".." ~ sep ~ sep ~ sep ~ sep) == "..");
assert(normPath("." ~ sep) == ".");
assert(normPath(sep ~ "." ~ sep ~ "file") == sep ~ "file");
assert(normPath(r"~\dir") == r"~\dir");
assert(normPath("~") == "~");
assert(normPath(sep ~ "..") == sep);
assert(normPath(sep ~ ".." ~ sep) == sep);
assert(normPath(sep ~ ".." ~ sep ~ "dir") == sep ~ "dir");
assert(normPath(sep ~ "..file") == sep ~ "..file");
assert(normPath(sep ~ ".file") == sep ~ ".file");
assert(normPath(".file") == ".file");
assert(normPath("file.") == "file.");
assert(normPath("file.file" ~ sep ~ "." ~ sep ~ "dir1" ~ sep ~
"dir2" ~ sep ~ "..") == "file.file" ~ sep ~ "dir1");
assert(normPath("file$.") == "file$.");
}
// normCase
unittest
{
version(Windows)
{
assert(normCase(r"C:/dir1\file1/dir2/File2") ==
r"c:\dir1\file1\dir2\file2");
}
else version(linux)
{
assert(normCase(r"/Dir1\file1\DIR2/file2") ==
r"/Dir1\file1\DIR2/file2");
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
}
// normSep
unittest
{
version(Windows)
{
assert(normSep(r"c:/dir\file") == r"c:\dir\file");
}
else version(linux)
{
assert(normSep(r"\dir1/dir2\file") == r"\dir1/dir2\file");
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
}
// join
unittest
{
assert(join(r"\dir/file", "file2", r"file3\file4") == r"\dir/file"
~ sep ~ "file2" ~ sep ~ r"file3\file4");
assert(join(r"\dir1\file") == r"\dir1\file");
assert(join(r"\dir1\file", r"dir2\file") == r"\dir1\file" ~ sep ~
r"dir2\file");
assert(join(r"\dir1\file", r"dir2\file", r"dir3\file") ==
r"\dir1\file" ~ sep ~ r"dir2\file" ~ sep ~ r"dir3\file");
assert(join("file1", "file2", "file3", "file4") == "file1" ~ sep ~
"file2" ~ sep ~ "file3" ~ sep ~ "file4");
assert(join("file1", "file2"w, "file3"d, "file4"c) == "file1" ~ sep
~ "file2" ~ sep ~ "file3" ~ sep ~ "file4");
assert(join("f", "i"w, "l"d, "e"c) == "f" ~ sep ~ "i" ~ sep ~ "l" ~
sep ~ "e");
char c = 'i'; wchar w = 'l'; dchar d = 'e';
assert(join("f", c, w, d) == "f" ~ sep ~ "i" ~ sep ~ "l" ~ sep ~ "e");
assert(join('f', 'i', 'l', 'e') == "f" ~ sep ~ "i" ~ sep ~ "l" ~
sep ~ "e");
version(Windows)
{
assert(join("file1", r"\dir1\file2") == r"\dir1\file2");
assert(join(r"\file1", r"\dir1") == r"\dir1");
assert(join(r"\file1", "dir1", r"c:\dir2\file2") == r"c:\dir2\file2");
assert(join("file1", r"\dir1", r"c:\dir2", r"d:\dir3", r"file3") ==
r"d:\dir3\file3");
}
version(linux)
{
assert(join("file1", r"/dir1\file2") == r"/dir1\file2");
assert(join(r"\file1", r"\dir1") == r"\file1/\dir1");
assert(join(r"\file1", "dir1", r"c:\dir2\file2") ==
r"\file1/dir1/c:\dir2\file2");
assert(join("file1", r"\dir1", r"c:\dir2", r"d:\dir3", r"file3") ==
r"file1/\dir1/c:\dir2/d:\dir3/file3");
}
}
// absPath
unittest
{
version(Windows)
{
assert(absPath(r"c:\dir1\file1\") == r"c:\dir1\file1");
}
else version(linux)
{
assert(absPath("file") == std.path.join(getcwd(), "file"));
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
assert(absPath("file") == std.path.join(getcwd(), "file"));
assert(absPath(r"\dir1\file") == std.path.join(getcwd(),
r"\dir1\file"));
assert(absPath(getcwd()));
assert(absPath(absPath(getcwd())));
assert(absPath(absPath(getDirName(getcwd()))));
}
// expandPath
unittest
{
version(Windows)
{
assert(expandPath("", "u:") == getcwd() ~ sep ~ "u:");
assert(expandPath("", r"u:\") == r"u:\");
assert(expandPath("", r"u:\dir1") == r"u:\dir1");
assert(expandPath("", r"u:\dir1\") == r"u:\dir1");
assert(expandPath("", r"u:\dir1\file\..") == r"u:\dir1");
assert(expandPath("", r"u:\dir1\..\file\.") == r"u:\file");
assert(expandPath("", r"\dir1\\:file") == getcwd() ~ r"\dir1\:file");
assert(expandPath("", r"\:dir1\\file") == getcwd() ~ r"\:dir1\file");
assert(expandPath("", "u:") == getcwd() ~ r"\u:");
assert(expandPath("", r"u:\") == r"u:\");
assert(expandPath("", r"u:\dir1") == r"u:\dir1");
assert(expandPath("", r"u:\dir1\") == r"u:\dir1");
assert(expandPath("", r"u:\dir1\file\..") == r"u:\dir1");
assert(expandPath("", r"u:\dir1\..\file\.") == r"u:\file");
assert(expandPath("file", r"p:\" ~ "dir1") == r"p:\" ~ "dir1" ~ sep
~ "file");
assert(expandPath("file", r"p:\" ~ "dir1" ~ sep) == r"p:\" ~ "dir1"
~ sep ~ "file");
assert(expandPath("file", r"p:\" ~ "dir1" ~ sep ~ sep) == r"p:\" ~
"dir1" ~ sep ~ "file");
assert(expandPath("file", "p:\\dir1\\\\dir2\\") == "p:" ~ sep ~
"dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(expandPath("file",
"p:\\dir1\\\\dir2\\\\\\dir3\\\\\\\\dir4\\\\") == "p:" ~ sep ~ "dir1" ~
sep ~ "dir2" ~ sep ~ "dir3" ~ sep ~ "dir4" ~ sep ~ "file");
assert(expandPath("file", "p:") == getcwd() ~ sep ~ "p:" ~ sep ~
"file");
assert(expandPath("file", "p:\\") == "p:" ~ sep ~ "file");
assert(expandPath("file" , "p:\\dir\\.") == "p:" ~ sep ~ "dir" ~
sep ~ "file");
assert(expandPath("file" , "p:\\dir1\\.\\dir2\\") == "p:" ~ sep ~
"dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(expandPath("file" , "p:\\dir1\\.\\dir2\\.") == "p:" ~ sep ~
"dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(expandPath("file" , "p:\\dir1\\.\\dir2\\.\\") == "p:" ~ sep
~ "dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(expandPath("", r"\") == getcwd());
assert(expandPath("", r"\dir1") == getcwd() ~ r"\dir1");
assert(expandPath("", r"\dir1\\file") == getcwd() ~ r"\dir1\file");
assert(expandPath("", r"\..\dir1\\file") == getDirName(getcwd()) ~
r"\dir1\file");
assert(expandPath("", r"\\\dir1\\file\\..\\dir2\\dir3\\..") ==
getcwd() ~ r"\dir1\dir2");
assert(expandPath("file") == getcwd() ~ r"\file");
assert(expandPath(r"\dir\file") == getcwd() ~ r"\dir\file");
assert(expandPath("file", r"\dir") == getcwd() ~ r"\dir\file");
assert(expandPath("file", r"....\") == getcwd() ~ sep ~ "...." ~
sep ~ "file");
assert(expandPath("file", "a.\\") == getcwd() ~ sep ~ "a." ~ sep ~
"file");
assert(expandPath("file", "..\\..") ==
getDirName(getDirName(getcwd())) ~ sep ~ "file");
assert(expandPath("file", "..\\..\\") ==
getDirName(getDirName(getcwd())) ~ sep ~ "file");
assert(expandPath("file", "..\\..\\..\\") ==
getDirName(getDirName(getDirName(getcwd()))) ~ sep ~ "file");
assert(expandPath("file", "..\\..\\..\\..\\") ==
getDirName(getDirName(getDirName(getDirName(getcwd())))) ~ sep ~ "file");
assert(expandPath("file" , ".\\dir") == getcwd() ~ sep ~ "dir" ~
sep ~ "file");
assert(expandPath("file" , "dir1\\.") == getcwd() ~ sep ~ "dir1" ~
sep ~ "file");
assert(expandPath("file" , "dir1\\.\\dir2") == getcwd() ~ sep ~
"dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(expandPath("file" , ".\\dir1\\.\\dir2") == getcwd() ~ sep ~
"dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(expandPath("file" , ".\\dir1\\.\\dir2\\.") == getcwd() ~ sep
~ "dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(expandPath("file" , ".\\..\\..\\.\\.") ==
getDirName(getDirName(getcwd())) ~ sep ~ "file");
assert(expandPath("file", ".\\..\\.\\.\\..\\") ==
getDirName(getDirName(getcwd())) ~ sep ~ "file");
assert(expandPath("file" , r"\\.\\dir1\\.\\dir2\\.") == getcwd() ~
sep ~ "dir1" ~ sep ~ "dir2" ~ sep ~ "file");
assert(expandPath("file", "\\.\\") == getcwd() ~ sep ~ "file");
assert(expandPath("file", "\\") == getcwd() ~ sep ~ "file");
assert(expandPath("file", "\\\\") == getcwd() ~ sep ~ "file");
assert(expandPath("file", "\\..\\..") ==
getDirName(getDirName(getcwd())) ~ sep ~ "file");
assert(expandPath("file", r"c:\..\..") == r"c:\file");
assert(expandPath("file", "\\..\\..\\") ==
getDirName(getDirName(getcwd())) ~ sep ~ "file");
assert(expandPath(r"\dir1\dir2/file", "/refdir") == getcwd() ~ sep
~ "refdir" ~ sep ~ "dir1" ~ sep ~ "dir2" ~ sep ~ "file");
}
else version(linux)
{
assert(expandPath("file") == getcwd() ~ "/file");
assert(expandPath(r"/dir/file") == "/dir/file");
assert(expandPath("file", "/dir") == "/dir/file");
assert(expandPath("", r"\") == getcwd() ~ r"/\");
assert(expandPath("", "/") == "/");
assert(expandPath("", r"\dir1") == getcwd() ~ r"/\dir1");
assert(expandPath("", r"\dir1\\file") == getcwd() ~ r"/\dir1\\file");
assert(expandPath("", r"/dir1\\file///file2") == r"/dir1\\file/file2");
assert(expandPath("", r"\..\dir1\\file") == getcwd() ~
r"/\..\dir1\\file");
assert(expandPath("", r"\\\dir1\\file\\..\\dir2\\dir3\\..") ==
getcwd() ~ r"/\\\dir1\\file\\..\\dir2\\dir3\\..");
assert(expandPath("", r"/dir1/file/../dir2/dir3/..") == "/dir1/dir2");
assert(expandPath("file") == getcwd() ~ "/file");
assert(expandPath(r"\dir\file") == getcwd() ~ r"/\dir\file");
assert(expandPath(r"/dir\file") == r"/dir\file");
assert(expandPath("file", r"\dir") == getcwd() ~ r"/\dir/file");
assert(expandPath("file", r"....\") == getcwd() ~ sep ~ r"....\" ~
sep ~ "file");
assert(expandPath("file", r"a.\") == getcwd() ~ sep ~ r"a.\" ~ sep
~ "file");
assert(expandPath("file", r"..\..") == getcwd() ~ r"/..\../file");
assert(expandPath("file", "../..") ==
getDirName(getDirName(getcwd())) ~ sep ~ "file");
assert(expandPath("file", r"..\..\") == getcwd() ~ r"/..\..\/file");
assert(expandPath("file", "../../") ==
getDirName(getDirName(getcwd())) ~ sep ~ "file");
assert(expandPath("file", r"..\..\..\") == getcwd() ~
r"/..\..\..\/file");
assert(expandPath("file", "../../../") ==
getDirName(getDirName(getDirName(getcwd()))) ~ sep ~ "file");
assert(expandPath("file", r"..\..\..\..\") == getcwd() ~
r"/..\..\..\..\/file");
assert(expandPath("file", "../../../../") ==
getDirName(getDirName(getDirName(getDirName(getcwd())))) ~ sep ~ "file");
assert(expandPath("file", r".\dir") == getcwd() ~ r"/.\dir/file");
assert(expandPath("file", r"dir1\.") == getcwd() ~ r"/dir1\./file");
assert(expandPath("file", r"dir1\.\dir2") == getcwd() ~
r"/dir1\.\dir2/file");
assert(expandPath("file", r".\dir1\.\dir2") == getcwd() ~
r"/.\dir1\.\dir2/file");
assert(expandPath("file", r".\dir1\.\dir2\.") == getcwd() ~
r"/.\dir1\.\dir2\./file");
assert(expandPath("file", r".\..\..\.\.") == getcwd() ~
r"/.\..\..\.\./file");
assert(expandPath("file", "./../.././.") ==
getDirName(getDirName(getcwd())) ~ sep ~ "file");
assert(expandPath("file", r".\..\.\.\..\") == getcwd() ~
r"/.\..\.\.\..\/file");
assert(expandPath("file", "./../././../") ==
getDirName(getDirName(getcwd())) ~ sep ~ "file");
assert(expandPath("file" , r"\\.\\dir1\\.\\dir2\\.") == getcwd() ~
r"/\\.\\dir1\\.\\dir2\\./file");
assert(expandPath("file" , "//.//dir1//.//dir2//.") == sep ~ "dir1"
~ sep ~ "dir2" ~ sep ~ "file");
assert(expandPath("file", r"\.\") == getcwd() ~ r"/\.\/file");
assert(expandPath("file", r"\") == getcwd() ~ r"/\/file");
assert(expandPath("file", r"\\") == getcwd() ~ r"/\\/file");
assert(expandPath("file", r"\..\..") == getcwd() ~ r"/\..\../file");
assert(expandPath("file", "/../..") == "/file");
assert(expandPath("file", r"\..\..\") == getcwd() ~ r"/\..\..\/file");
assert(expandPath(r"\dir1\dir2/file", "/refdir") ==
r"/refdir/\dir1\dir2/file");
}
else
{
pragma(msg, "Unsupported OS");
static assert(0);
}
assert(expandPath("") == "");
assert(expandPath("file") == getcwd() ~ sep ~ "file");
assert(expandPath("file", "") == getcwd() ~ sep ~ "file");
assert(expandPath("file", "..") == getDirName(getcwd()) ~ sep ~
"file");
assert(expandPath("..") == getDirName(getcwd()));
assert(expandPath(getcwd()));
assert(expandPath(getcwd(), ""));
assert(expandPath(getcwd(), getcwd()));
assert(expandPath(getcwd(), "refdir"));
}
Jul 30 2006
Kramer wrote:I have some functions for the path module that I'd like to submit to the general public. I haven't worked on them for about half a year and I had submitted them to Walter for inclusion into Phobos a while back, but he's got far more pressing issues (like bug fixes and spec. stability) to concern himself with.Seems nice (haven't used yet though, maybe in the future, for shell scripting). And indeed it seems like it would be a good addition for Phobos (std.path). -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Aug 17 2006
Bruno Medeiros wrote:Kramer wrote:Thanks. Hopefully, they're useful. :) -KramerI have some functions for the path module that I'd like to submit to the general public. I haven't worked on them for about half a year and I had submitted them to Walter for inclusion into Phobos a while back, but he's got far more pressing issues (like bug fixes and spec. stability) to concern himself with.Seems nice (haven't used yet though, maybe in the future, for shell scripting). And indeed it seems like it would be a good addition for Phobos (std.path).
Aug 17 2006









Kramer <Kramer_member pathlink.com> 