I'm tired of strange, obscure regex crashes. Use PCRE instead of GNU
regex.
Reenable d3d error messages.
Put my missing code back in. Don't revert large sections of important
code; report bugs and get them fixed. (Without this, "IsAFile("foo\bar")
will fail on Unix.)
This commit is contained in:
+175
-5
@@ -18,7 +18,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "regex.h"
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
@@ -139,8 +138,8 @@ CString vssprintf( const char *fmt, va_list argList)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
//#include "dxerr8.h"
|
#include "dxerr8.h"
|
||||||
//#pragma comment(lib, "DxErr8.lib")
|
#pragma comment(lib, "DxErr8.lib")
|
||||||
|
|
||||||
CString hr_ssprintf( int hr, const char *fmt, ...)
|
CString hr_ssprintf( int hr, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -149,7 +148,9 @@ CString hr_ssprintf( int hr, const char *fmt, ...)
|
|||||||
CString s = vssprintf( fmt, va );
|
CString s = vssprintf( fmt, va );
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
return s;// += ssprintf( " (%s)", DXGetErrorString8(hr) );
|
/* Why was this commented out? -glenn */
|
||||||
|
return s + ssprintf( " (%s)", DXGetErrorString8(hr) );
|
||||||
|
// return s;// += ssprintf( " (%s)", DXGetErrorString8(hr) );
|
||||||
}
|
}
|
||||||
|
|
||||||
CString werr_ssprintf( int err, const char *fmt, ...)
|
CString werr_ssprintf( int err, const char *fmt, ...)
|
||||||
@@ -430,7 +431,11 @@ unsigned GetFileSizeInBytes( const CString &sFilePath )
|
|||||||
|
|
||||||
return st.st_size;
|
return st.st_size;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
bool DoesFileExist( const CString &sPath ) { return FDB.DoesFileExist(sPath); }
|
||||||
|
bool IsAFile( const CString &sPath ) { return FDB.IsAFile(sPath); }
|
||||||
|
bool IsADirectory( const CString &sPath ) { return FDB.IsADirectory(sPath); }
|
||||||
|
#else
|
||||||
bool DoesFileExist( const CString &sPath )
|
bool DoesFileExist( const CString &sPath )
|
||||||
{
|
{
|
||||||
if(sPath.empty()) return false;
|
if(sPath.empty()) return false;
|
||||||
@@ -452,6 +457,7 @@ bool IsADirectory( const CString &sPath )
|
|||||||
|
|
||||||
return !!(st.st_mode & S_IFDIR);
|
return !!(st.st_mode & S_IFDIR);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool CompareCStringsAsc(const CString &str1, const CString &str2)
|
bool CompareCStringsAsc(const CString &str1, const CString &str2)
|
||||||
{
|
{
|
||||||
@@ -556,6 +562,104 @@ CString GetRedirContents(const CString &path)
|
|||||||
return sNewFileName;
|
return sNewFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/* PCRE */
|
||||||
|
#include "pcre/pcre.h"
|
||||||
|
void Regex::Compile()
|
||||||
|
{
|
||||||
|
const char *error;
|
||||||
|
int offset;
|
||||||
|
reg = pcre_compile(pattern.c_str(), PCRE_CASELESS, &error, &offset, NULL);
|
||||||
|
|
||||||
|
if(reg == NULL)
|
||||||
|
RageException::Throw("Invalid regex: '%s' (%s)", pattern.c_str(), error);
|
||||||
|
|
||||||
|
int ret = pcre_fullinfo( (pcre *) reg, NULL, PCRE_INFO_CAPTURECOUNT, &backrefs);
|
||||||
|
ASSERT(ret >= 0);
|
||||||
|
|
||||||
|
backrefs++;
|
||||||
|
ASSERT(backrefs < 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Regex::Set(const CString &str)
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
pattern=str;
|
||||||
|
Compile();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Regex::Release()
|
||||||
|
{
|
||||||
|
pcre_free(reg);
|
||||||
|
reg = NULL;
|
||||||
|
pattern = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Regex::Regex(const CString &str)
|
||||||
|
{
|
||||||
|
reg = NULL;
|
||||||
|
Set(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
Regex::Regex(const Regex &rhs)
|
||||||
|
{
|
||||||
|
reg = NULL;
|
||||||
|
Set(rhs.pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
Regex &Regex::operator=(const Regex &rhs)
|
||||||
|
{
|
||||||
|
if(this != &rhs) Set(rhs.pattern);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Regex::~Regex()
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Regex::Compare(const CString &str)
|
||||||
|
{
|
||||||
|
int mat[128*3];
|
||||||
|
int ret = pcre_exec( (pcre *) reg, NULL,
|
||||||
|
str.data(), str.size(), 0, 0, mat, 128*3);
|
||||||
|
|
||||||
|
if( ret < -1 )
|
||||||
|
RageException::Throw("Unexpected return from pcre_exec('%s'): %i",
|
||||||
|
pattern.c_str(), ret);
|
||||||
|
|
||||||
|
return ret >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Regex::Compare(const CString &str, vector<CString> &matches)
|
||||||
|
{
|
||||||
|
matches.clear();
|
||||||
|
|
||||||
|
int mat[128*3];
|
||||||
|
int ret = pcre_exec( (pcre *) reg, NULL,
|
||||||
|
str.data(), str.size(), 0, 0, mat, 128*3);
|
||||||
|
|
||||||
|
if( ret < -1 )
|
||||||
|
RageException::Throw("Unexpected return from pcre_exec('%s'): %i",
|
||||||
|
pattern.c_str(), ret);
|
||||||
|
|
||||||
|
if(ret == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for(unsigned i = 1; i < backrefs; ++i)
|
||||||
|
{
|
||||||
|
const int start = mat[i*2], end = mat[i*2+1];
|
||||||
|
if(start == -1)
|
||||||
|
matches.push_back(""); /* no match */
|
||||||
|
else
|
||||||
|
matches.push_back(str.substr(start, end - start));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* GNU regex */
|
||||||
|
#include "regex.h"
|
||||||
void Regex::Compile()
|
void Regex::Compile()
|
||||||
{
|
{
|
||||||
reg = new regex_t;
|
reg = new regex_t;
|
||||||
@@ -633,6 +737,7 @@ bool Regex::Compare(const CString &str, vector<CString> &matches)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* UTF-8 decoding code from glib. */
|
/* UTF-8 decoding code from glib. */
|
||||||
char *utf8_find_next_char (const char *p, const char *end)
|
char *utf8_find_next_char (const char *p, const char *end)
|
||||||
@@ -927,6 +1032,9 @@ struct FileSet
|
|||||||
const CString &beginning, const CString &containing, const CString &ending,
|
const CString &beginning, const CString &containing, const CString &ending,
|
||||||
vector<CString> &out, bool bOnlyDirs) const;
|
vector<CString> &out, bool bOnlyDirs) const;
|
||||||
void GetFilesEqualTo(const CString &pat, vector<CString> &out, bool bOnlyDirs) const;
|
void GetFilesEqualTo(const CString &pat, vector<CString> &out, bool bOnlyDirs) const;
|
||||||
|
bool DoesFileExist(const CString &path) const;
|
||||||
|
bool IsADirectory(const CString &path) const;
|
||||||
|
bool IsAFile(const CString &path) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
void FileSet::LoadFromDir(const CString &dir)
|
void FileSet::LoadFromDir(const CString &dir)
|
||||||
@@ -1024,6 +1132,68 @@ void FileSet::GetFilesEqualTo(const CString &str, vector<CString> &out, bool bOn
|
|||||||
out.push_back(i->name.c_str());
|
out.push_back(i->name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FileSet::DoesFileExist(const CString &path) const
|
||||||
|
{
|
||||||
|
return files.find(File(path.c_str())) != files.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileSet::IsADirectory(const CString &path) const
|
||||||
|
{
|
||||||
|
set<File>::const_iterator i = files.find(File(path.c_str()));
|
||||||
|
if(i == files.end())
|
||||||
|
return false;
|
||||||
|
return i->dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileSet::IsAFile(const CString &path) const
|
||||||
|
{
|
||||||
|
set<File>::const_iterator i = files.find(File(path.c_str()));
|
||||||
|
if(i == files.end())
|
||||||
|
return false;
|
||||||
|
return !i->dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given "foo/bar/baz/" or "foo/bar/baz", return "foo/bar/" and "baz". */
|
||||||
|
static void SplitPath( CString Path, CString &Dir, CString &Name )
|
||||||
|
{
|
||||||
|
/* Must always have at least one slash. */
|
||||||
|
static Regex split("(.*/)([^/]+)");
|
||||||
|
CStringArray match;
|
||||||
|
if(split.Compare(Path, match)) {
|
||||||
|
Dir = match[0];
|
||||||
|
Name = match[1];
|
||||||
|
} else {
|
||||||
|
/* No slash. */
|
||||||
|
Dir = "./";
|
||||||
|
Name = Path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilenameDB::DoesFileExist( const CString &sPath )
|
||||||
|
{
|
||||||
|
CString Dir, Name;
|
||||||
|
SplitPath(sPath, Dir, Name);
|
||||||
|
FileSet &fs = GetFileSet(Dir);
|
||||||
|
return fs.DoesFileExist(Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilenameDB::IsAFile( const CString &sPath )
|
||||||
|
{
|
||||||
|
CString Dir, Name;
|
||||||
|
SplitPath(sPath, Dir, Name);
|
||||||
|
FileSet &fs = GetFileSet(Dir);
|
||||||
|
return fs.IsAFile(Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilenameDB::IsADirectory( const CString &sPath )
|
||||||
|
{
|
||||||
|
CString Dir, Name;
|
||||||
|
SplitPath(sPath, Dir, Name);
|
||||||
|
FileSet &fs = GetFileSet(Dir);
|
||||||
|
return fs.IsADirectory(Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* XXX: this won't work right for URIs, eg \\foo\bar */
|
/* XXX: this won't work right for URIs, eg \\foo\bar */
|
||||||
bool FilenameDB::ResolvePath(CString &path)
|
bool FilenameDB::ResolvePath(CString &path)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user