|
|
|
@@ -79,9 +79,9 @@ String File::parseAbsolutePath (const String& p) |
|
|
|
// Windows..
|
|
|
|
String path (p.replaceCharacter ('/', '\\'));
|
|
|
|
|
|
|
|
if (path.startsWithChar (File::separator))
|
|
|
|
if (path.startsWithChar (separator))
|
|
|
|
{
|
|
|
|
if (path[1] != File::separator)
|
|
|
|
if (path[1] != separator)
|
|
|
|
{
|
|
|
|
/* When you supply a raw string to the File object constructor, it must be an absolute path.
|
|
|
|
If you're trying to parse a string that may be either a relative path or an absolute path,
|
|
|
|
@@ -120,7 +120,7 @@ String File::parseAbsolutePath (const String& p) |
|
|
|
|
|
|
|
if (path.startsWithChar ('~'))
|
|
|
|
{
|
|
|
|
if (path[1] == File::separator || path[1] == 0)
|
|
|
|
if (path[1] == separator || path[1] == 0)
|
|
|
|
{
|
|
|
|
// expand a name of the form "~/abc"
|
|
|
|
path = File::getSpecialLocation (File::userHomeDirectory).getFullPathName()
|
|
|
|
@@ -136,7 +136,7 @@ String File::parseAbsolutePath (const String& p) |
|
|
|
path = addTrailingSeparator (pw->pw_dir) + path.fromFirstOccurrenceOf ("/", false, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (! path.startsWithChar (File::separator))
|
|
|
|
else if (! path.startsWithChar (separator))
|
|
|
|
{
|
|
|
|
/* When you supply a raw string to the File object constructor, it must be an absolute path.
|
|
|
|
If you're trying to parse a string that may be either a relative path or an absolute path,
|
|
|
|
@@ -159,8 +159,8 @@ String File::parseAbsolutePath (const String& p) |
|
|
|
|
|
|
|
String File::addTrailingSeparator (const String& path)
|
|
|
|
{
|
|
|
|
return path.endsWithChar (File::separator) ? path
|
|
|
|
: path + File::separator;
|
|
|
|
return path.endsWithChar (separator) ? path
|
|
|
|
: path + separator;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
@@ -391,7 +391,7 @@ File File::getChildFile (String relativePath) const |
|
|
|
{
|
|
|
|
if (relativePath[1] == '.')
|
|
|
|
{
|
|
|
|
if (relativePath [2] == 0 || relativePath[2] == separator)
|
|
|
|
if (relativePath[2] == 0 || relativePath[2] == separator)
|
|
|
|
{
|
|
|
|
const int lastSlash = path.lastIndexOfChar (separator);
|
|
|
|
if (lastSlash >= 0)
|
|
|
|
@@ -810,6 +810,24 @@ String File::createLegalFileName (const String& original) |
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
static int countNumberOfSeparators (String::CharPointerType s)
|
|
|
|
{
|
|
|
|
int num = 0;
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
const juce_wchar c = s.getAndAdvance();
|
|
|
|
|
|
|
|
if (c == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (c == File::separator)
|
|
|
|
++num;
|
|
|
|
}
|
|
|
|
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
|
|
|
String File::getRelativePathFrom (const File& dir) const
|
|
|
|
{
|
|
|
|
String thisPath (fullPath);
|
|
|
|
@@ -820,57 +838,54 @@ String File::getRelativePathFrom (const File& dir) const |
|
|
|
String dirPath (addTrailingSeparator (dir.existsAsFile() ? dir.getParentDirectory().getFullPathName()
|
|
|
|
: dir.fullPath));
|
|
|
|
|
|
|
|
const int len = jmin (thisPath.length(), dirPath.length());
|
|
|
|
int commonBitLength = 0;
|
|
|
|
String::CharPointerType thisPathAfterCommon (thisPath.getCharPointer());
|
|
|
|
String::CharPointerType dirPathAfterCommon (dirPath.getCharPointer());
|
|
|
|
|
|
|
|
{
|
|
|
|
String::CharPointerType thisPathIter (thisPath.getCharPointer());
|
|
|
|
String::CharPointerType dirPathIter (dirPath.getCharPointer());
|
|
|
|
String::CharPointerType dirPathIter (dirPath.getCharPointer());
|
|
|
|
|
|
|
|
for (int i = 0; i < len; ++i)
|
|
|
|
for (int i = 0;;)
|
|
|
|
{
|
|
|
|
const juce_wchar c1 = thisPathIter.getAndAdvance();
|
|
|
|
const juce_wchar c2 = dirPathIter.getAndAdvance();
|
|
|
|
|
|
|
|
#if NAMES_ARE_CASE_SENSITIVE
|
|
|
|
if (c1 != c2)
|
|
|
|
if (c1 != c2
|
|
|
|
#else
|
|
|
|
if (c1 != c2 && CharacterFunctions::toLowerCase (c1) != CharacterFunctions::toLowerCase (c2))
|
|
|
|
if ((c1 != c2 && CharacterFunctions::toLowerCase (c1) != CharacterFunctions::toLowerCase (c2))
|
|
|
|
#endif
|
|
|
|
|| c1 == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
++commonBitLength;
|
|
|
|
++i;
|
|
|
|
|
|
|
|
if (c1 == separator)
|
|
|
|
{
|
|
|
|
thisPathAfterCommon = thisPathIter;
|
|
|
|
dirPathAfterCommon = dirPathIter;
|
|
|
|
commonBitLength = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (commonBitLength > 0 && thisPath [commonBitLength - 1] != File::separator)
|
|
|
|
--commonBitLength;
|
|
|
|
|
|
|
|
// if the only common bit is the root, then just return the full path..
|
|
|
|
if (commonBitLength <= 0
|
|
|
|
|| (commonBitLength == 1 && thisPath [1] == File::separator))
|
|
|
|
if (commonBitLength == 0 || (commonBitLength == 1 && thisPath[1] == separator))
|
|
|
|
return fullPath;
|
|
|
|
|
|
|
|
thisPath = thisPath.substring (commonBitLength);
|
|
|
|
dirPath = dirPath.substring (commonBitLength);
|
|
|
|
|
|
|
|
while (dirPath.isNotEmpty())
|
|
|
|
{
|
|
|
|
#if JUCE_WINDOWS
|
|
|
|
thisPath = "..\\" + thisPath;
|
|
|
|
#else
|
|
|
|
thisPath = "../" + thisPath;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
const int sep = dirPath.indexOfChar (separator);
|
|
|
|
const int numUpDirectoriesNeeded = countNumberOfSeparators (dirPathAfterCommon);
|
|
|
|
|
|
|
|
if (sep >= 0)
|
|
|
|
dirPath = dirPath.substring (sep + 1);
|
|
|
|
else
|
|
|
|
dirPath = String::empty;
|
|
|
|
}
|
|
|
|
if (numUpDirectoriesNeeded == 0)
|
|
|
|
return thisPathAfterCommon;
|
|
|
|
|
|
|
|
return thisPath;
|
|
|
|
#if JUCE_WINDOWS
|
|
|
|
String s (String::repeatedString ("..\\", numUpDirectoriesNeeded));
|
|
|
|
#else
|
|
|
|
String s (String::repeatedString ("../", numUpDirectoriesNeeded));
|
|
|
|
#endif
|
|
|
|
s.appendCharPointer (thisPathAfterCommon);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
|