OSDN Git Service

Try again to fix issue #1646, #1644: Filtering qualified files
authorTakashi Sawanaka <sdottaka@users.sourceforge.net>
Thu, 16 Feb 2023 13:52:12 +0000 (22:52 +0900)
committerTakashi Sawanaka <sdottaka@users.sourceforge.net>
Thu, 16 Feb 2023 13:52:12 +0000 (22:52 +0900)
Src/DirScan.cpp
Src/FileFilter.h
Src/FileFilterHelper.cpp
Src/FileFilterMgr.cpp
Src/FolderCmp.cpp
Src/Plugins.cpp
Testing/GoogleTest/FileFilter/FileFilterHelper_test.cpp

index 2e71991..8b7fcca 100644 (file)
@@ -863,9 +863,15 @@ static void CompareDiffItem(FolderCmp &fc, DIFFITEM &di)
        {
                // 1. Test against filters
                if (pCtxt->m_piFilterGlobal==nullptr ||
-                       (nDirs == 2 && pCtxt->m_piFilterGlobal->includeFile(di.diffFileInfo[0].filename, di.diffFileInfo[1].filename)) ||
-                       (nDirs == 3 && pCtxt->m_piFilterGlobal->includeFile(di.diffFileInfo[0].filename, di.diffFileInfo[1].filename, di.diffFileInfo[2].filename))
-                       )
+                       (nDirs == 2 && pCtxt->m_piFilterGlobal->includeFile(
+                               paths::ConcatPath(di.diffFileInfo[0].path, di.diffFileInfo[0].filename), 
+                               paths::ConcatPath(di.diffFileInfo[1].path, di.diffFileInfo[1].filename)
+                       )) ||
+                       (nDirs == 3 && pCtxt->m_piFilterGlobal->includeFile(
+                               paths::ConcatPath(di.diffFileInfo[0].path, di.diffFileInfo[0].filename),
+                               paths::ConcatPath(di.diffFileInfo[1].path, di.diffFileInfo[1].filename),
+                               paths::ConcatPath(di.diffFileInfo[2].path, di.diffFileInfo[2].filename)
+                       )))
                {
                        di.diffcode.diffcode |= DIFFCODE::INCLUDED;
                        di.diffcode.diffcode |= fc.prepAndCompareFiles(di);
index 3f9ea16..ceb33db 100644 (file)
@@ -29,10 +29,13 @@ struct FileFilterElement
        Poco::RegularExpression regexp; /**< Compiled regular expression */
        std::string _regex; /**< Regular expression string to set to Poco::RegularExpression */
        int _reOpts; /**< Options to set to Poco::RegularExpression */
-       FileFilterElement(const std::string& regex, int reOpts) : regexp(regex, reOpts), _regex(regex), _reOpts(reOpts)
+       bool _fileNameOnly; /**< If true, indicates that the filter matches only filenames */
+       FileFilterElement(const std::string& regex, int reOpts, bool fileFilter) :
+               regexp(regex, reOpts), _regex(regex), _reOpts(reOpts), _fileNameOnly(fileFilter && regex.find("\\\\", 0) == String::npos && regex.find_first_of(":/") == String::npos)
        {
        }
-       FileFilterElement(const FileFilterElement* element) : regexp(element->_regex, element->_reOpts), _regex(element->_regex), _reOpts(element->_reOpts)
+       FileFilterElement(const FileFilterElement* element) :
+               regexp(element->_regex, element->_reOpts), _regex(element->_regex), _reOpts(element->_reOpts), _fileNameOnly(element->_fileNameOnly)
        {
        }
 };
index b9c444e..e71e0ac 100644 (file)
@@ -194,6 +194,37 @@ void FileFilterHelper::SetMask(const String& strMask)
                m_pMaskDirFilter->AddRegExp(regexp_str_dir_excluded, true);
 }
 
+static String addPeriodIfNoExtension(const String& path)
+{
+       String ret, elm;
+       bool period = false;
+       for (auto ch : path)
+       {
+               if (ch == '.')
+               {
+                       elm += ch;
+                       period = true;
+               }
+               else if (ch == '\\')
+               {
+                       if (!period && !elm.empty() && elm.back() != '*')
+                               elm += '.';
+                       elm += ch;
+                       ret += elm;
+                       elm.clear();
+                       period = false;
+               }
+               else
+               {
+                       elm += ch;
+               }
+       }
+       if (!period && !elm.empty())
+               elm += '.';
+       ret += elm;
+       return ret;
+}
+
 /**
  * @brief Check if any of filefilter rules match to filename.
  *
@@ -214,8 +245,7 @@ bool FileFilterHelper::includeFile(const String& szFileName) const
                if (strFileName.empty() || strFileName[0] != '\\')
                        strFileName = _T("\\") + strFileName;
                // append a point if there is no extension
-               if (strFileName.find('.') == String::npos)
-                       strFileName = strFileName + _T(".");
+               strFileName = addPeriodIfNoExtension(strFileName);
 
                return m_pMaskFileFilter->Match(ucr::toUTF8(strFileName));
        }
@@ -247,8 +277,7 @@ bool FileFilterHelper::includeDir(const String& szDirName) const
                if (strDirName.empty() || strDirName[0] != '\\')
                        strDirName = _T("\\") + strDirName;
                // append a point if there is no extension
-               if (strDirName.find('.') == String::npos)
-                       strDirName = strDirName + _T(".");
+               strDirName = addPeriodIfNoExtension(strDirName);
 
                return m_pMaskDirFilter->Match(ucr::toUTF8(strDirName));
        }
@@ -334,8 +363,7 @@ std::tuple<String, String, String, String> FileFilterHelper::ParseExtensions(con
                        bool isdir = token.back() == '\\';
                        if (isdir)
                                token = token.substr(0, token.size() - 1);
-                       if (token.find('.') == String::npos && !token.empty() && token.back() != '*')
-                               token += _T(".");
+                       token = addPeriodIfNoExtension(token);
                        String strRegex = strutils::makelower(ConvertWildcardPatternToRegexp(token));
                        if (exclude)
                        {
index 4e81c75..c02aa92 100644 (file)
@@ -23,7 +23,7 @@ using Poco::Glob;
 using Poco::icompare;
 using Poco::RegularExpression;
 
-static void AddFilterPattern(vector<FileFilterElementPtr> *filterList, String & str);
+static void AddFilterPattern(vector<FileFilterElementPtr> *filterList, String & str, bool fileFilter);
 
 /**
  * @brief Destructor, frees all filters.
@@ -119,7 +119,7 @@ void FileFilterMgr::DeleteAllFilters()
  * @param [in] filterList List where pattern is added.
  * @param [in] str Temporary variable (ie, it may be altered)
  */
-static void AddFilterPattern(vector<FileFilterElementPtr> *filterList, String & str)
+static void AddFilterPattern(vector<FileFilterElementPtr> *filterList, String & str, bool fileFilter)
 {
        const String& commentLeader = _T("##"); // Starts comment
        str = strutils::trim_ws_begin(str);
@@ -145,7 +145,7 @@ static void AddFilterPattern(vector<FileFilterElementPtr> *filterList, String &
        re_opts |= RegularExpression::RE_UTF8;
        try
        {
-               filterList->push_back(FileFilterElementPtr(new FileFilterElement(regexString, re_opts)));
+               filterList->push_back(FileFilterElementPtr(new FileFilterElement(regexString, re_opts, fileFilter)));
        }
        catch (...)
        {
@@ -218,25 +218,25 @@ FileFilter * FileFilterMgr::LoadFilterFile(const String& szFilepath, int & error
                {
                        // file filter
                        String str = sLine.substr(2);
-                       AddFilterPattern(&pfilter->filefilters, str);
+                       AddFilterPattern(&pfilter->filefilters, str, true);
                }
                else if (0 == sLine.compare(0, 2, _T("d:"), 2))
                {
                        // directory filter
                        String str = sLine.substr(2);
-                       AddFilterPattern(&pfilter->dirfilters, str);
+                       AddFilterPattern(&pfilter->dirfilters, str, false);
                }
                else if (0 == sLine.compare(0, 3, _T("f!:"), 3))
                {
                        // file filter
                        String str = sLine.substr(3);
-                       AddFilterPattern(&pfilter->filefiltersExclude, str);
+                       AddFilterPattern(&pfilter->filefiltersExclude, str, true);
                }
                else if (0 == sLine.compare(0, 3, _T("d!:"), 3))
                {
                        // directory filter
                        String str = sLine.substr(3);
-                       AddFilterPattern(&pfilter->dirfiltersExclude, str);
+                       AddFilterPattern(&pfilter->dirfiltersExclude, str, false);
                }
        } while (bLinesLeft);
 
@@ -289,7 +289,7 @@ bool TestAgainstRegList(const vector<FileFilterElementPtr> *filterList, const St
        if (filterList->size() == 0)
                return false;
 
-       std::string compString;
+       std::string compString, compStringFileName;
        ucr::toUTF8(szTest, compString);
        vector<FileFilterElementPtr>::const_iterator iter = filterList->begin();
        while (iter != filterList->end())
@@ -297,7 +297,9 @@ bool TestAgainstRegList(const vector<FileFilterElementPtr> *filterList, const St
                RegularExpression::Match match;
                try
                {
-                       if ((*iter)->regexp.match(compString, 0, match) > 0)
+                       if ((*iter)->_fileNameOnly && compStringFileName.empty())
+                               ucr::toUTF8(paths::FindFileName(szTest), compStringFileName);
+                       if ((*iter)->regexp.match((*iter)->_fileNameOnly ? compStringFileName : compString, 0, match) > 0)
                                return true;
                }
                catch (...)
index 12e32c7..983b6b5 100644 (file)
@@ -78,9 +78,12 @@ int FolderCmp::prepAndCompareFiles(DIFFITEM &di)
                        nCompMethod = CMP_BINARY_CONTENT;
                }
                else if (m_pCtxt->m_bEnableImageCompare && (
-                       di.diffFileInfo[0].size != DirItem::FILE_SIZE_NONE && m_pCtxt->m_pImgfileFilter->includeFile(di.diffFileInfo[0].filename) ||
-                       di.diffFileInfo[1].size != DirItem::FILE_SIZE_NONE && m_pCtxt->m_pImgfileFilter->includeFile(di.diffFileInfo[1].filename) ||
-                       nDirs > 2 && di.diffFileInfo[2].size != DirItem::FILE_SIZE_NONE && m_pCtxt->m_pImgfileFilter->includeFile(di.diffFileInfo[2].filename)))
+                       di.diffFileInfo[0].size != DirItem::FILE_SIZE_NONE && m_pCtxt->m_pImgfileFilter->includeFile(
+                               paths::ConcatPath(di.diffFileInfo[0].path, di.diffFileInfo[0].filename)) ||
+                       di.diffFileInfo[1].size != DirItem::FILE_SIZE_NONE && m_pCtxt->m_pImgfileFilter->includeFile(
+                               paths::ConcatPath(di.diffFileInfo[1].path, di.diffFileInfo[1].filename)) ||
+                       nDirs > 2 && di.diffFileInfo[2].size != DirItem::FILE_SIZE_NONE && m_pCtxt->m_pImgfileFilter->includeFile(
+                               paths::ConcatPath(di.diffFileInfo[2].path, di.diffFileInfo[2].filename))))
                {
                        nCompMethod = CMP_IMAGE_CONTENT;
                }
index 28be9c9..8f1a375 100644 (file)
@@ -246,7 +246,7 @@ void PluginInfo::LoadFilterString()
                re_opts |= RegularExpression::RE_UTF8;
                try
                {
-                       m_filters.emplace_back(std::make_shared<FileFilterElement>(regexString, re_opts));
+                       m_filters.emplace_back(std::make_shared<FileFilterElement>(regexString, re_opts, true));
                }
                catch (...)
                {
index cfd23b5..fc02508 100644 (file)
@@ -218,6 +218,23 @@ namespace
                EXPECT_EQ(false, m_fileFilterHelper.includeDir(_T("Debug")));
                EXPECT_EQ(false, m_fileFilterHelper.includeDir(_T("dir1\\Debug")));
 
+               m_fileFilterHelper.SetMask(_T("abc.\\def.\\*.*"));
+               EXPECT_EQ(true, m_fileFilterHelper.IsUsingMask());
+               EXPECT_EQ(true, m_fileFilterHelper.includeFile(_T("abc\\def\\efg")));
+               EXPECT_EQ(false, m_fileFilterHelper.includeFile(_T("abc.1\\def\\efg")));
+               EXPECT_EQ(false, m_fileFilterHelper.includeFile(_T("abc\\def.1\\efg")));
+
+               m_fileFilterHelper.SetMask(_T("abc.\\def.\\"));
+               EXPECT_EQ(true, m_fileFilterHelper.IsUsingMask());
+               EXPECT_EQ(true, m_fileFilterHelper.includeDir(_T("abc\\def")));
+               EXPECT_EQ(false, m_fileFilterHelper.includeDir(_T("abc.1\\def")));
+               EXPECT_EQ(false, m_fileFilterHelper.includeDir(_T("abc\\def.1")));
+
+               // Test for bugs introduced in version 2.16.26
+               m_fileFilterHelper.SetMask(_T("*.*"));
+               EXPECT_EQ(true, m_fileFilterHelper.IsUsingMask());
+               EXPECT_EQ(true, m_fileFilterHelper.includeFile(_T(".git\\config")));
+
        }