Handle up to two wildcards in GetDirListing

This commit is contained in:
Glenn Maynard
2003-02-24 07:07:56 +00:00
parent 848ff56bbc
commit ab3c8e47b1
2 changed files with 44 additions and 30 deletions
+41 -29
View File
@@ -963,22 +963,6 @@ struct File {
bool operator== (const File &rhs) const { return name==rhs.name; }
bool operator< (const File &rhs) const { return name<rhs.name; }
bool FilenameBeginsWith(const CString &txt) const
{
if(txt.empty()) return true;
if(txt.size() > name.size()) return false;
return !strnicmp(name.c_str(), txt.c_str(), txt.size());
}
bool FilenameEndsWith(const CString &ext) const
{
if(ext.empty()) return true;
int ignore = int(name.size())-int(ext.size());
if(ignore < 0) return false;
return !stricmp(name.c_str()+ignore, ext.c_str());
}
bool equal(const File &rhs) const { return name == rhs.name; }
bool equal(const CString &rhs) const {
return !stricmp(name.c_str(), rhs.c_str());
@@ -993,7 +977,9 @@ struct FileSet
set<File> files;
RageTimer age;
void LoadFromDir(const CString &dir);
void GetFilesStartingAndEndingWith(const CString &beginning, const CString &ending, vector<CString> &out, bool bOnlyDirs) const;
void GetFilesMatching(
const CString &beginning, const CString &containing, const CString &ending,
vector<CString> &out, bool bOnlyDirs) const;
void GetFilesEqualTo(const CString &pat, vector<CString> &out, bool bOnlyDirs) const;
};
@@ -1048,15 +1034,33 @@ void FileSet::LoadFromDir(const CString &dir)
chdir(oldpath);
}
void FileSet::GetFilesStartingAndEndingWith(const CString &beginning, const CString &ending, vector<CString> &out, bool bOnlyDirs) const
/* Search for "beginning*containing*ending". */
void FileSet::GetFilesMatching(const CString &beginning, const CString &containing, const CString &ending, vector<CString> &out, bool bOnlyDirs) const
{
set<File>::const_iterator i = files.lower_bound(File(beginning.c_str()));
// set<File>::const_iterator end = files.upper_bound(File(beginning.c_str()));
for( ; i != files.end(); ++i)
{
if(bOnlyDirs && !i->dir) continue;
if(!i->FilenameBeginsWith(beginning)) return;
if(!i->FilenameEndsWith(ending)) continue;
/* Check beginning. */
if(beginning.size() > i->name.size()) continue; /* can't start with it */
if(strnicmp(i->name.c_str(), beginning.c_str(), beginning.size())) continue; /* doesn't start with it */
/* Position the end starts on: */
int end_pos = int(i->name.size())-int(ending.size());
/* Check end. */
if(end_pos < 0) continue; /* can't end with it */
if(stricmp(i->name.c_str()+end_pos, ending.c_str())) continue; /* doesn't end with it */
/* Check containing. Do this last, since it's the slowest (substring
* search instead of string match). */
if(containing.size())
{
unsigned pos = i->name.find(containing, beginning.size());
if(pos == i->name.npos) continue; /* doesn't contain it */
if(pos + containing.size() > unsigned(end_pos)) continue; /* found it but it overlaps with the end */
}
out.push_back(i->name.c_str());
}
@@ -1113,10 +1117,10 @@ bool FilenameDB::ResolvePath(CString &path)
return true;
}
void FilenameDB::GetFilesStartingAndEndingWith(const CString &dir, const CString &beginning, const CString &ending, vector<CString> &out, bool bOnlyDirs)
void FilenameDB::GetFilesMatching(const CString &dir, const CString &beginning, const CString &containing, const CString &ending, vector<CString> &out, bool bOnlyDirs)
{
FileSet &fs = GetFileSet(dir);
fs.GetFilesStartingAndEndingWith(beginning, ending, out, bOnlyDirs);
fs.GetFilesMatching(beginning, containing, ending, out, bOnlyDirs);
}
void FilenameDB::GetFilesEqualTo(const CString &dir, const CString &fn, vector<CString> &out, bool bOnlyDirs)
@@ -1129,16 +1133,24 @@ void FilenameDB::GetFilesEqualTo(const CString &dir, const CString &fn, vector<C
void FilenameDB::GetFilesSimpleMatch(const CString &dir, const CString &fn, vector<CString> &out, bool bOnlyDirs)
{
/* Does this contain a wildcard? */
unsigned pos = fn.find_first_of('*');
if(pos == fn.npos)
unsigned first_pos = fn.find_first_of('*');
if(first_pos == fn.npos)
{
/* No; just do a regular search. */
GetFilesEqualTo(dir, fn, out, bOnlyDirs);
} else {
/* Only one *! */
if(pos)
ASSERT(fn.find_first_of('*', pos+1) == fn.npos);
GetFilesStartingAndEndingWith(dir, fn.substr(0, pos), fn.substr(pos+1), out, bOnlyDirs);
unsigned second_pos = fn.find_first_of('*', first_pos+1);
if(second_pos == fn.npos)
{
/* Only one *: "A*B". */
GetFilesMatching(dir, fn.substr(0, first_pos), "", fn.substr(first_pos+1), out, bOnlyDirs);
} else {
/* Two *s: "A*B*C". */
GetFilesMatching(dir,
fn.substr(0, first_pos),
fn.substr(first_pos+1, second_pos-first_pos-1),
fn.substr(second_pos+1), out, bOnlyDirs);
}
}
}