Mercurial > octave
changeset 28204:9a1b6400c706 stable
Canonicalize case of long parts of path on Windows file systems (bug #58148).
* file-ops.cc (canonicalize_file_name): Call GetShortPathNameW before
GetLongPathNameW to also get actual letter case for parts of the path that are
longer than the 8.3 short file names.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Sat, 11 Apr 2020 20:46:24 +0200 |
parents | 6c88000fed48 |
children | 1ef597f9b0bb 11d66485fc19 |
files | liboctave/system/file-ops.cc |
diffstat | 1 files changed, 15 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/system/file-ops.cc Sat Apr 11 08:19:45 2020 -0400 +++ b/liboctave/system/file-ops.cc Sat Apr 11 20:46:24 2020 +0200 @@ -736,14 +736,25 @@ if (! w_tmp.empty ()) { // Get a more canonical name wrt case and full names - wchar_t w_long[32767] = L""; - int w_len = GetLongPathNameW (w_tmp.c_str (), w_long, 32767); + // FIXME: To make this work on partitions that don't store short file + // names, use FindFirstFileW on each component of the path. + // Insufficient access permissions on parent folders might make this + // tricky. + + // Parts of the path that wouldn't fit into a short 8.3 file name are + // copied as is by GetLongPathNameW. To also get the correct case + // for these parts, first convert to short file names and than back + // to long. + wchar_t buffer[32767] = L""; + int w_len = GetShortPathNameW (w_tmp.c_str (), buffer, 32767); + w_len = GetLongPathNameW (buffer, buffer, 32767); if (! strip_marker) - retval = u8_from_wstring (std::wstring (w_long, w_len)); + retval = u8_from_wstring (std::wstring (buffer, w_len)); else if (w_len > 4) - retval = u8_from_wstring (std::wstring (w_long+4, w_len-4)); + retval = u8_from_wstring (std::wstring (buffer+4, w_len-4)); + // If root is a drive, use an upper case letter for the drive letter. if (retval.length () > 1 && retval[1] == ':') retval[0] = toupper (retval[0]); }