Mercurial > octave
changeset 32219:792733e11f87
dir_entry: Support paths with non-ASCII characters on Windows (bug #64447).
* dir-ops.cc (dir_entry::open): On Windows, check if a directory with the given
name exists. Set m_dir to a dummy value.
(dir_entry::read): Use wide character Windows API functions to allow traversing
directories with non-ASCII characters in their name.
(dir_entry::close): On Windows, set the dummy DIR pointer to nullptr.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Mon, 24 Jul 2023 18:21:18 +0200 |
parents | 3de184236b48 |
children | e0dbf8def91c |
files | liboctave/system/dir-ops.cc |
diffstat | 1 files changed, 41 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/system/dir-ops.cc Fri Jul 28 18:52:56 2023 +0200 +++ b/liboctave/system/dir-ops.cc Mon Jul 24 18:21:18 2023 +0200 @@ -34,6 +34,10 @@ #include <list> #include <string> +#if defined (OCTAVE_USE_WINDOWS_API) +# include "windows.h" +#endif + #include "dirent-wrappers.h" #include "dir-ops.h" @@ -58,10 +62,24 @@ std::string fullname = sys::file_ops::tilde_expand (m_name); +#if defined (OCTAVE_USE_WINDOWS_API) + std::string msg; + + if (sys::dir_exists (fullname, msg)) + // Never dereference this pointer! + // We just need something that is non-null. + m_dir = reinterpret_cast<void *> (1); + else + { + m_dir = nullptr; + m_errmsg = msg; + } +#else m_dir = octave_opendir_wrapper (fullname.c_str ()); if (! m_dir) m_errmsg = std::strerror (errno); +#endif } else m_errmsg = "dir_entry::open: empty filename"; @@ -78,10 +96,29 @@ { std::list<std::string> dirlist; +#if defined (OCTAVE_USE_WINDOWS_API) + WIN32_FIND_DATAW find_file_data; + std::wstring pattern = u8_to_wstring (m_name + "\\*"); + std::string file_name; + + HANDLE h_find_file = FindFirstFileW (pattern.c_str (), &find_file_data); + if (h_find_file != INVALID_HANDLE_VALUE) + { + do + { + file_name = u8_from_wstring (find_file_data.cFileName); + dirlist.push_back (file_name); + } + while (FindNextFileW (h_find_file, &find_file_data)); + + FindClose (h_find_file); + } +#else char *fname; while ((fname = octave_readdir_wrapper (m_dir))) dirlist.push_back (fname); +#endif retval = string_vector (dirlist); } @@ -94,12 +131,16 @@ { bool retval = true; +#if defined (OCTAVE_USE_WINDOWS_API) + m_dir = nullptr; +#else if (m_dir) { retval = (octave_closedir_wrapper (m_dir) == 0); m_dir = nullptr; } +#endif return retval; }