Mercurial > octave
changeset 29073:f39e75f35e48
__wglob__: Fix some issues with native implementation on Windows.
* liboctave/util/oct-glob.cc (find_files): Remove multiple directory separators.
Do not include "." and ".." (when matching "*").
(windows_glob): Don't fail if input is only a disc root (without file or
folder).
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Sat, 14 Nov 2020 18:07:21 +0100 |
parents | a0be96cd13c5 |
children | a5e267bc2930 |
files | liboctave/util/oct-glob.cc |
diffstat | 1 files changed, 32 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/util/oct-glob.cc Thu Nov 19 08:30:13 2020 -0800 +++ b/liboctave/util/oct-glob.cc Sat Nov 14 18:07:21 2020 +0100 @@ -39,6 +39,7 @@ #if defined (OCTAVE_USE_WINDOWS_API) # include <windows.h> +# include <shlwapi.h> # include <wchar.h> # include "lo-sysdep.h" @@ -154,8 +155,12 @@ static void find_files (std::list<std::string>& dirlist, const std::string& dir, - const std::string& pat, const std::string& file) + const std::string& pat, std::string& file) { + // remove leading file separators + while (file.length () > 1 && sys::file_ops::is_dir_sep (file[0])) + file = file.substr (1, std::string::npos); + // find first file in directory that matches pattern in PAT std::wstring wpat = u8_to_wstring (sys::file_ops::concat (dir, pat)); _WIN32_FIND_DATAW ffd; @@ -172,11 +177,15 @@ std::string found_dir = u8_from_wstring (ffd.cFileName); if (file.empty ()) - dirlist.push_back (sys::file_ops::concat (dir, found_dir)); + { + if (found_dir.compare (".") && found_dir.compare ("..")) + dirlist.push_back (sys::file_ops::concat (dir, found_dir)); + } else { // get next component of path (or file name) - size_t sep_pos = file.find_first_of (sys::file_ops::dir_sep_chars ()); + size_t sep_pos + = file.find_first_of (sys::file_ops::dir_sep_chars ()); std::string pat_str = file.substr (0, sep_pos); std::string file_str = (sep_pos != std::string::npos && file.length () > sep_pos+1) @@ -221,15 +230,33 @@ std::string dir = ""; - if (sep_pos == 2 && xpat[1] == ':') + if ((sep_pos == 2 || xpat.length () == 2) && xpat[1] == ':') { - // include disc root + // include disc root with first file or folder + + // remove leading file separators in path without disc root + while (file.length () > 1 && sys::file_ops::is_dir_sep (file[0])) + file = file.substr (1, std::string::npos); + sep_pos = file.find_first_of (sys::file_ops::dir_sep_chars ()); dir = xpat; xpat = file.substr (0, sep_pos); file = (sep_pos != std::string::npos && file.length () > sep_pos+1) ? file.substr (sep_pos+1) : ""; + if (xpat.empty ()) + { + // don't glob if input is only disc root + if (PathFileExistsA (pat(i).c_str ())) + { + if (sys::file_ops::is_dir_sep (pat(i).back ())) + dirlist.push_back (dir + + sys::file_ops::dir_sep_char ()); + else + dirlist.push_back (dir); + } + continue; + } } find_files (dirlist, dir, xpat, file);