Skip to content

Commit

Permalink
path::Normalize() => NormalizeTemp(); tweak rename file
Browse files Browse the repository at this point in the history
  • Loading branch information
kjk committed Sep 19, 2024
1 parent ebc0e72 commit d0d76d2
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 46 deletions.
30 changes: 18 additions & 12 deletions src/SumatraPDF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1633,6 +1633,7 @@ void UpdateAfterThemeChange() {
}

static void RenameFileInHistory(const char* oldPath, const char* newPath) {
logf("RenameFileInHistory: oldPath: '%s', newPath: '%s'\n", oldPath, newPath);
if (path::IsSame(oldPath, newPath)) {
return;
}
Expand Down Expand Up @@ -3027,13 +3028,13 @@ static void RenameCurrentFile(MainWindow* win) {
fileFilter.AppendFmt("\1*%s\1", defExt);
str::TransCharsInPlace(fileFilter.Get(), "\1", "\0");

WCHAR dstFileName[MAX_PATH];
WCHAR dstFilePathW[MAX_PATH];
auto baseName = path::GetBaseNameTemp(srcPath);
str::BufSet(dstFileName, dimof(dstFileName), baseName);
str::BufSet(dstFilePathW, dimof(dstFilePathW), baseName);
// Remove the extension so that it can be re-added depending on the chosen filter
if (str::EndsWithI(dstFileName, defExtW)) {
int idx = str::Leni(dstFileName) - str::Leni(defExtW);
dstFileName[idx] = '\0';
if (str::EndsWithI(dstFilePathW, defExtW)) {
int idx = str::Leni(dstFilePathW) - str::Leni(defExtW);
dstFilePathW[idx] = '\0';
}

WCHAR* srcPathW = ToWStrTemp(srcPath);
Expand All @@ -3042,8 +3043,8 @@ static void RenameCurrentFile(MainWindow* win) {
OPENFILENAME ofn{};
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = win->hwndFrame;
ofn.lpstrFile = dstFileName;
ofn.nMaxFile = dimof(dstFileName);
ofn.lpstrFile = dstFilePathW;
ofn.nMaxFile = dimof(dstFilePathW);
ofn.lpstrFilter = ToWStrTemp(fileFilter);
ofn.nFilterIndex = 1;
// note: the other two dialogs are named "Open" and "Save As"
Expand All @@ -3057,13 +3058,20 @@ static void RenameCurrentFile(MainWindow* win) {
if (!ok) {
return;
}
TempStr dstFilePath = ToUtf8Temp(dstFilePathW);
TempStr dstPathNormalized = path::NormalizeTemp(dstFilePath);
logf("RenameCurrentFile: '%s' => '%s'\n", srcPath, dstFilePath);
logf(" dstPathNormalized: '%s'\n", dstPathNormalized);
if (path::IsSame(dstFilePath, dstPathNormalized)) {
return;
}

UpdateTabFileDisplayStateForTab(win->CurrentTab());
CloseDocumentInCurrentTab(win, true, true);
HwndSetFocus(win->hwndFrame);

DWORD flags = MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING;
BOOL moveOk = MoveFileExW(srcPathW, dstFileName, flags);
BOOL moveOk = MoveFileExW(srcPathW, dstFilePathW, flags);
if (!moveOk) {
LogLastError();
LoadArgs args(srcPath, win);
Expand All @@ -3077,11 +3085,9 @@ static void RenameCurrentFile(MainWindow* win) {
ShowNotification(nargs);
return;
}
char* dstFilePath = ToUtf8Temp(dstFileName);
char* newPath = path::NormalizeTemp(dstFilePath);
RenameFileInHistory(srcPath, newPath);
RenameFileInHistory(srcPath, dstPathNormalized);

LoadArgs args(newPath, win);
LoadArgs args(dstPathNormalized, win);
args.forceReuse = true;
LoadDocument(&args);
}
Expand Down
66 changes: 33 additions & 33 deletions src/utils/FileUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,67 +230,67 @@ WCHAR* Join(const WCHAR* path, const WCHAR* fileName, const WCHAR* fileName2) {
// e.g. suppose the a file "C:\foo\Bar.Pdf" exists on the file system then
// "c:\foo\bar.pdf" becomes "c:\foo\Bar.Pdf"
// "C:\foo\BAR.PDF" becomes "C:\foo\Bar.Pdf"
WCHAR* Normalize(const WCHAR* path) {
static TempWStr NormalizeTemp(const WCHAR* path) {
// convert to absolute path, change slashes into backslashes
DWORD cch = GetFullPathNameW(path, 0, nullptr, nullptr);
if (!cch) {
return str::Dup(path);
return str::DupTemp(path);
}

AutoFreeWStr fullpath(AllocArray<WCHAR>(cch));
GetFullPathNameW(path, cch, fullpath, nullptr);
TempWStr fullPath = AllocArrayTemp<WCHAR>(cch);
GetFullPathNameW(path, cch, fullPath, nullptr);
// convert to long form
cch = GetLongPathNameW(fullpath, nullptr, 0);
cch = GetLongPathNameW(fullPath, nullptr, 0);
if (!cch) {
return fullpath.StealData();
return fullPath;
}

AutoFreeWStr normpath(AllocArray<WCHAR>(cch));
GetLongPathNameW(fullpath, normpath, cch);
TempWStr normPath = AllocArrayTemp<WCHAR>(cch);
GetLongPathNameW(fullPath, normPath, cch);
if (cch <= MAX_PATH) {
return normpath.StealData();
return normPath;
}

// handle overlong paths: first, try to shorten the path
cch = GetShortPathNameW(fullpath, nullptr, 0);
cch = GetShortPathNameW(fullPath, nullptr, 0);
if (cch && cch <= MAX_PATH) {
AutoFreeWStr shortpath(AllocArray<WCHAR>(cch));
GetShortPathNameW(fullpath, shortpath, cch);
if (str::Len(path::GetBaseNameTemp(normpath)) + path::GetBaseNameTemp(shortpath) - shortpath < MAX_PATH) {
TempWStr shortPath = AllocArrayTemp<WCHAR>(cch);
GetShortPathNameW(fullPath, shortPath, cch);
TempWStr shortPathName = (TempWStr)path::GetBaseNameTemp(shortPath);
TempWStr normPathName = (TempWStr)path::GetBaseNameTemp(normPath);
if (str::Len(normPathName) + shortPathName - shortPath < MAX_PATH) {
// keep the long filename if possible
*(WCHAR*)path::GetBaseNameTemp(shortpath) = '\0';
return str::Join(shortpath, path::GetBaseNameTemp(normpath));
*shortPathName = 0;
return str::JoinTemp(shortPath, path::GetBaseNameTemp(normPath));
}
return shortpath.StealData();
return shortPath;
}
// else mark the path as overlong
if (str::StartsWith(normpath.Get(), L"\\\\?\\")) {
return normpath.StealData();
if (str::StartsWith(normPath, L"\\\\?\\")) {
return normPath;
}
return str::Join(L"\\\\?\\", normpath);
return str::JoinTemp(L"\\\\?\\", normPath);
}

char* NormalizeTemp(const char* path) {
WCHAR* s = ToWStrTemp(path);
AutoFreeWStr ws = Normalize(s);
char* res = ToUtf8Temp(ws);
TempStr NormalizeTemp(const char* path) {
TempWStr s = ToWStrTemp(path);
TempWStr ws = NormalizeTemp(s);
TempStr res = ToUtf8Temp(ws);
return res;
}

// Normalizes the file path and the converts it into a short form that
// can be used for interaction with non-UNICODE aware applications
TempStr ShortPathTemp(const char* pathA) {
WCHAR* path = ToWStrTemp(pathA);
AutoFreeWStr normpath = Normalize(path);
DWORD cch = GetShortPathNameW(normpath, nullptr, 0);
TempStr ShortPathTemp(const char* path) {
TempWStr pathW = ToWStrTemp(path);
TempWStr normPath = NormalizeTemp(pathW);
DWORD cch = GetShortPathNameW(normPath, nullptr, 0);
if (!cch) {
return ToUtf8(normpath.Get());
return ToUtf8Temp(normPath);
}
WCHAR* shortPath = AllocArray<WCHAR>(cch + 1);
GetShortPathNameW(normpath, shortPath, cch);
char* res = ToUtf8Temp(shortPath);
str::Free(shortPath);
return res;
TempWStr shortPath = AllocArrayTemp<WCHAR>(cch + 1);
GetShortPathNameW(normPath, shortPath, cch);
return ToUtf8Temp(shortPath);
}

static bool IsSameFileHandleInformation(BY_HANDLE_FILE_INFORMATION& fi1, BY_HANDLE_FILE_INFORMATION fi2) {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/FileUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ TempWStr JoinTemp(const WCHAR* path, const WCHAR* fileName, const WCHAR* fileNam

bool IsDirectory(const char*);

char* NormalizeTemp(const char* path);
TempStr NormalizeTemp(const char* path);

TempStr ShortPathTemp(const char* pathA);
bool IsSame(const char* path1, const char* path2);
Expand Down

0 comments on commit d0d76d2

Please sign in to comment.