Skip to content

Commit

Permalink
Merge branch 'db/LH-4/fix-win7-path-handling'
Browse files Browse the repository at this point in the history
* db/LH-4/fix-win7-path-handling:
  Common.cpp: PathXXX functions on Windows 7 fix

[#4 state:resolved]

Signed-off-by: Thell Fowler <git@tbfowler.name>
  • Loading branch information
Thell Fowler committed Nov 28, 2009
2 parents 9aeb7da + 2a4b252 commit 71c6fdd
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 108 deletions.
128 changes: 20 additions & 108 deletions PowerEditor/src/MISC/Common/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include "precompiled_headers.h"

#include "npp_winver.h"

WcharMbcsConvertor * WcharMbcsConvertor::_pSelf = new WcharMbcsConvertor;

// Set a call back with the handle after init to set the path.
Expand Down Expand Up @@ -529,7 +531,21 @@ BOOL PathRemoveFileSpec(generic_string & path)
else if (lastBackslash == 0 && path.size() > 1) // "\foo.exe" becomes "\"
path.erase(1);
else
{
path.erase(lastBackslash);

// For multiple backslashes as the last backslash, windows 7 onwards removes them
// The version check is done if and only if the last character is still a backslash
// which will only happen in the case of c:\foo\\bar
if (path[path.size() - 1] == TEXT('\\') && getWinVersion() >= WV_WIN7)
{
do
{
lastBackslash--;
path.erase(lastBackslash);
} while (path[path.size() - 1] == TEXT('\\'));
}
}
}

return inLen != path.length();
Expand Down Expand Up @@ -565,114 +581,10 @@ BOOL PathAppend(generic_string &path, const generic_string &more)

BOOL PathCanonicalize(generic_string& path)
{
generic_string::size_type position = path.size();
generic_string::size_type lastPosition = position;
generic_string::size_type removeFrom = position;
generic_string::size_type stopAt = 0;

int upDirElements = 0;
int sameDirElements = 0;

/* Note this mirrors a bug with win32 PathCanonicalize not supporting
* relative paths with drive letters (e.g. C:abc\\def)
*/
if (position >= 3 && path.compare(1, 2, TEXT(":\\")) == 0)
{
stopAt = 2;
}


do
{
position = path.find_last_of(TEXT('\\'), position);
if (generic_string::npos == position)
position = 0;


if (path.compare(position, lastPosition - position, TEXT("\\..")) == 0)
{
if (0 == sameDirElements && 0 == upDirElements)
removeFrom = lastPosition;

upDirElements++;

}
else if (path.compare(position, lastPosition - position, TEXT("\\.")) == 0)
{
if (0 == sameDirElements && 0 == upDirElements)
removeFrom = lastPosition;

sameDirElements++;

}
else if (0 == position && path.compare(position, lastPosition - position, TEXT("..")) == 0)
{
// Special case for .. at the start of the path

if (0 == sameDirElements && 0 == upDirElements)
removeFrom = lastPosition;

upDirElements++;
}
else if (0 == position && path.compare(position, lastPosition - position, TEXT(".")) == 0)
{
// Special case for . at the start of the path

if (0 == sameDirElements && 0 == upDirElements)
removeFrom = lastPosition;

sameDirElements++;
}
else
{
if (upDirElements > 1)
{
upDirElements--;
}
else if (1 == upDirElements)
{
// strip the \.. and the dir that precedes it (or however many there are
// e.g. abc\def\ghi\..\..\jkl becomes abc\jkl
path.erase(position, removeFrom - position);

upDirElements = 0;
sameDirElements = 0;
}
else if (sameDirElements > 0)
{
path.erase(lastPosition, removeFrom - lastPosition);
sameDirElements = 0;
}

}

lastPosition = position;
if (position > 0)
position--;


} while (lastPosition > stopAt);



if (upDirElements > 0)
{
// if any .. path elements remain at the beginning of the path, just remove and leave the backslash
path.erase(stopAt, removeFrom - stopAt);
}
else if (sameDirElements > 0)
{
// if any . path elements remain, remove them, and leave the backslash only if it was there before
if (path[stopAt] == TEXT('\\'))
path.erase(stopAt, removeFrom - stopAt);
else
path.erase(stopAt, removeFrom + 1 - stopAt);
}



return TRUE;

TCHAR buffer[MAX_PATH];
BOOL result = PathCanonicalize(buffer, path.c_str());
path = buffer;
return result;
}

BOOL PathCanonicalize(generic_string& path, generic_string& output)
Expand Down
13 changes: 13 additions & 0 deletions PowerEditor/tests/testCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ bool testPathAppend(TCHAR *path, TCHAR *append)
BOOL strRet = PathAppend(strPath, strAppend);
BOOL charRet = PathAppend(cPath, append);

if (strRet != charRet || strPath != cPath)
{
_tprintf(_T("Testing |%s| append |%s| String (ours) |%s| returned %d Char (system) |%s| returned %d\r\n"), path, append, strPath.c_str(), strRet, cPath, charRet);
}
return ((strRet == charRet) &&
(strPath == cPath));
}
Expand Down Expand Up @@ -250,6 +254,10 @@ bool testPathRemoveFileSpec(TCHAR* toTest)

BOOL strRet = PathRemoveFileSpec(strPath);
BOOL charRet = PathRemoveFileSpec(charPath);
if (strPath != charPath || strRet != charRet)
{
_tprintf(_T("Testing |%s| String(our version) |%s| returned %d Char(sys version) |%s| returned %d\r\n"), toTest, strPath.c_str(), strRet, charPath, charRet);
}

return ((strPath == charPath) &&
(strRet == charRet));
Expand Down Expand Up @@ -390,6 +398,11 @@ bool testPathCanonicalize(TCHAR *path)
BOOL charRet = PathCanonicalize(output, path);
BOOL strRet = PathCanonicalize(strPath);

if (charRet != strRet || strPath != output)
{
_tprintf(_T("Testing |%s| String (ours) |%s| returned %d Char (system) |%s| returned %d\r\n"), path, strPath.c_str(), strRet, output, charRet);
}

return ((charRet == strRet)
&& (strPath == output));
}
Expand Down

0 comments on commit 71c6fdd

Please sign in to comment.