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)
     {