Mercurial > octave
diff liboctave/system/lo-sysdep.cc @ 25516:8945a6a6c0eb
Add Unicode support for getting directory listing in Windows (bug #49118).
* lo-sysdep.[cc,h]: Add new function "get_dirlist".
* dirfns.cc, load-path.cc, gzip.cc, file-ops.cc, url-transfer.cc: Replace uses
of "dir_entry::read" with "get_dirlist".
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Fri, 29 Jun 2018 12:33:09 +0200 |
parents | c63f67d87b4a |
children | 7fbc39a46be8 |
line wrap: on
line diff
--- a/liboctave/system/lo-sysdep.cc Thu Jun 28 14:39:46 2018 +0200 +++ b/liboctave/system/lo-sysdep.cc Fri Jun 29 12:33:09 2018 +0200 @@ -26,12 +26,18 @@ #include <string> +#include "dir-ops.h" #include "file-ops.h" #include "lo-error.h" #include "lo-sysdep.h" #include "uniconv-wrappers.h" #include "unistd-wrappers.h" +#if defined (OCTAVE_USE_WINDOWS_API) +# include <windows.h> +# include <wchar.h> +#endif + namespace octave { namespace sys @@ -69,6 +75,71 @@ return octave_chdir_wrapper (path.c_str ()); } + bool + get_dirlist (const std::string& dirname, string_vector& dirlist, std::string& msg) + { + dirlist = ""; + msg = ""; +#if defined (OCTAVE_USE_WINDOWS_API) + _WIN32_FIND_DATAW ffd; + + std::string path_name (dirname); + if (path_name.empty ()) + return true; + + if (path_name.back () == '\\' || path_name.back () == '/') + path_name.push_back ('*'); + else + path_name.append (R"(\*)"); + + // Find first file in directory. + HANDLE hFind = FindFirstFileW (u8_to_wstring (path_name).c_str (), + &ffd); + if (INVALID_HANDLE_VALUE == hFind) + { + DWORD errCode = GetLastError (); + char *errorText; + FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errCode, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + errorText, 0, NULL); + if (errorText != NULL) + { + msg = std::string (errorText); + LocalFree (errorText); + } + return false; + } + + std::list<std::string> dirlist_str; + do + dirlist_str.push_back (u8_from_wstring (ffd.cFileName)); + while (FindNextFileW (hFind, &ffd) != 0); + + FindClose(hFind); + + dirlist = string_vector (dirlist_str); + +#else + + dir_entry dir (dirname); + + if (! dir) + { + msg = dir.error (); + return false; + } + + dirlist = dir.read (); + + dir.close (); +#endif + + return true; + } + std::wstring u8_to_wstring (const std::string& utf8_string) {