1 /////////////////////////////////////////////////////////////////////////////
2 // FileFilterMgr.cpp : implementation file
3 // see FileFilterMgr.h for description
4 /////////////////////////////////////////////////////////////////////////////
6 // This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
7 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8 // You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
9 /////////////////////////////////////////////////////////////////////////////
13 #include "FileFilterMgr.h"
19 static char THIS_FILE[] = __FILE__;
22 void DeleteRegList(RegList & reglist)
24 while (!reglist.IsEmpty())
26 CRegExp * regexp = reglist.RemoveHead();
31 // For example, this might be a GNU C filter, excluding *.o files and CVS directories
32 // That is to say, a filter is a set of file masks and directory masks
40 FileFilter() : default_include(true) { }
43 FileFilter::~FileFilter()
45 DeleteRegList(filefilters);
46 DeleteRegList(dirfilters);
49 FileFilterMgr::~FileFilterMgr()
55 void FileFilterMgr::LoadFromDirectory(LPCTSTR szPattern, LPCTSTR szExt)
57 // DeleteAllFilters();
59 BOOL bWorking = finder.FindFile(szPattern);
60 int extlen = szExt ? _tcslen(szExt) : 0;
63 bWorking = finder.FindNextFile();
64 if (finder.IsDots() || finder.IsDirectory())
66 CString sFilename = finder.GetFileName();
69 // caller specified a specific extension
70 // (This is really a workaround for brokenness in windows, which
71 // doesn't screen correctly on extension in pattern)
72 if (sFilename.Right(extlen).CompareNoCase(szExt))
75 FileFilter * pfilter = LoadFilterFile(finder.GetFilePath(), sFilename);
76 m_filters.Add(pfilter);
80 void FileFilterMgr::DeleteAllFilters()
82 for (int i=0; i<m_filters.GetSize(); ++i)
87 m_filters.RemoveAll();
90 // Add a single pattern (if nonempty & valid) to a pattern list
91 // str is a temporary variable (ie, it may be altered)
92 static void AddFilterPattern(RegList & reglist, CString & str)
96 LPCTSTR commentLeader = _T(" ##");
97 // anything from commentLeader to end of line is a comment
98 int comment = str.Find(commentLeader);
101 str = str.Left(comment);
103 if (str.IsEmpty()) return;
104 CRegExp * regexp = new CRegExp;
105 if (regexp->RegComp(str))
106 reglist.AddTail(regexp);
111 // Parse a filter file, and add it to array if valid
112 FileFilter * FileFilterMgr::LoadFilterFile(LPCTSTR szFilepath, LPCTSTR szFilename)
115 if (!file.Open(szFilepath, CFile::modeRead))
117 FileFilter *pfilter = new FileFilter;
118 pfilter->fullpath = szFilepath;
119 pfilter->name = szFilename; // default if no name
121 while (file.ReadString(sLine))
123 if (0 == _tcsncmp(sLine, _T("name:"), 5))
125 // specifies display name
126 CString str = sLine.Mid(5);
131 else if (0 == _tcsncmp(sLine, _T("def:"), 4))
134 CString str = sLine.Mid(4);
136 if (str == _T("0") || str == _T("no") || str == _T("exclude"))
137 pfilter->default_include = false;
138 else if (str == _T("1") || str == _T("yes") || str == _T("include"))
139 pfilter->default_include = true;
141 else if (0 == _tcsncmp(sLine, _T("f:"), 2))
144 CString str = sLine.Mid(2);
145 AddFilterPattern(pfilter->filefilters, str);
147 else if (0 == _tcsncmp(sLine, _T("d:"), 2))
150 CString str = sLine.Mid(2);
151 AddFilterPattern(pfilter->dirfilters, str);
157 // Give client back a pointer to the actual filter
158 // We just do a linear search, because this is seldom called
159 FileFilter * FileFilterMgr::GetFilterByPath(LPCTSTR szFilterPath)
161 for (int i=0; i<m_filters.GetSize(); ++i)
163 if (m_filters[i]->fullpath == szFilterPath)
169 // return TRUE if string passes
170 BOOL TestAgainstRegList(const RegList & reglist, LPCTSTR szTest)
172 CString str = szTest;
174 for (POSITION pos = reglist.GetHeadPosition(); pos; )
176 CRegExp * regexp = reglist.GetNext(pos);
177 if (regexp->RegFind(str) != -1)
183 // return TRUE if file passes the filter
184 BOOL FileFilterMgr::TestFileNameAgainstFilter(FileFilter * pFilter, LPCTSTR szFileName)
186 if (!pFilter) return TRUE;
187 if (TestAgainstRegList(pFilter->filefilters, szFileName))
188 return !pFilter->default_include;
189 return pFilter->default_include;
192 // return TRUE if directory passes the filter
193 BOOL FileFilterMgr::TestDirNameAgainstFilter(FileFilter * pFilter, LPCTSTR szDirName)
195 if (!pFilter) return TRUE;
196 if (TestAgainstRegList(pFilter->dirfilters, szDirName))
197 return !pFilter->default_include;
198 return pFilter->default_include;
201 CString FileFilterMgr::GetFilterName(int i) const
203 return m_filters[i]->name;
206 CString FileFilterMgr::GetFilterPath(int i) const
208 return m_filters[i]->fullpath;
211 CString FileFilterMgr::GetFullpath(FileFilter * pfilter) const
213 return pfilter->fullpath;
216 // Reload filter from disk (by creating a new one to substitute for old one)
217 void FileFilterMgr::ReloadFilterFromDisk(FileFilter * pfilter)
219 FileFilter * newfilter = LoadFilterFile(pfilter->fullpath, pfilter->name);
220 for (int i=0; i<m_filters.GetSize(); ++i)
222 if (pfilter == m_filters[i])
224 m_filters.RemoveAt(i);
229 m_filters.Add(newfilter);