gtkradiant/contrib/pk3man/wild.cpp
mattn caabb8dceb * added pk3man and fixed it to compile for latest radiant
* NOTE: Not included in the build chain - doesn't link
* NOTE: iepair.h is not used at the moment


git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/ZeroRadiant@225 8a3a26a2-13c4-0310-b231-cf6edde360e5
2008-03-18 17:11:08 +00:00

338 lines
6.6 KiB
C++

// Wild.cpp: implementation of the CWild class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
//#include "pakman.h"
#include "wild.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CWild::CWild()
{
}
CWild::~CWild()
{
}
int CWild::fpattern_isvalid(const char *pat)
{
int len;
/* Check args */
if (pat == NULL)
return (FALSE);
/* Verify that the pattern is valid */
for (len = 0; pat[len] != '\0'; len++)
{
switch (pat[len])
{
case FPAT_SET_L:
/* Char set */
len++;
if (pat[len] == FPAT_SET_NOT)
len++; /* Set negation */
while (pat[len] != FPAT_SET_R)
{
if (pat[len] == QUOTE)
len++; /* Quoted char */
if (pat[len] == '\0')
return (FALSE); /* Missing closing bracket */
len++;
if (pat[len] == FPAT_SET_THRU)
{
/* Char range */
len++;
if (pat[len] == QUOTE)
len++; /* Quoted char */
if (pat[len] == '\0')
return (FALSE); /* Missing closing bracket */
len++;
}
if (pat[len] == '\0')
return (FALSE); /* Missing closing bracket */
}
break;
case QUOTE:
/* Quoted char */
len++;
if (pat[len] == '\0')
return (FALSE); /* Missing quoted char */
break;
case FPAT_NOT:
/* Negated pattern */
len++;
if (pat[len] == '\0')
return (FALSE); /* Missing subpattern */
break;
default:
/* Valid character */
break;
}
}
return (TRUE);
}
int CWild::fpattern_submatch(const char *pat, const char *fname)
{
int fch;
int pch;
int i;
int yes, match;
int lo, hi;
/* Attempt to match subpattern against subfilename */
while (*pat != '\0')
{
fch = *fname;
pch = *pat;
pat++;
switch (pch)
{
case FPAT_ANY:
/* Match a single char */
if (fch == DEL || fch == DEL2 || fch == '\0')
return (FALSE);
fname++;
break;
case FPAT_CLOS:
/* Match zero or more chars */
i = 0;
while (fname[i] != '\0')// && fname[i] != DEL && fname[i] != DEL2)
i++;
while (i >= 0)
{
if (fpattern_submatch(pat, fname+i))
return (TRUE);
i--;
}
return (FALSE);
case SUB:
/* Match zero or more chars */
i = 0;
while (fname[i] != '\0' && fname[i] != DEL && fname[i] != DEL2 && fname[i] != '.')
i++;
while (i >= 0)
{
if (fpattern_submatch(pat, fname+i))
return (TRUE);
i--;
}
return (FALSE);
case QUOTE:
/* Match a quoted char */
pch = *pat;
if (lowercase(fch) != lowercase(pch) || pch == '\0')
return (FALSE);
fname++;
pat++;
break;
case FPAT_SET_L:
/* Match char set/range */
yes = TRUE;
if (*pat == FPAT_SET_NOT)
{
pat++;
yes = FALSE; /* Set negation */
}
/* Look for [s], [-], [abc], [a-c] */
match = !yes;
while (*pat != FPAT_SET_R && *pat != '\0')
{
if (*pat == QUOTE)
pat++; /* Quoted char */
if (*pat == '\0')
break;
lo = *pat++;
hi = lo;
if (*pat == FPAT_SET_THRU)
{
/* Range */
pat++;
if (*pat == QUOTE)
pat++; /* Quoted char */
if (*pat == '\0')
break;
hi = *pat++;
}
if (*pat == '\0')
break;
/* Compare character to set range */
if (lowercase(fch) >= lowercase(lo) &&
lowercase(fch) <= lowercase(hi))
match = yes;
}
if (!match)
return (FALSE);
if (*pat == '\0')
return (FALSE); /* Missing closing bracket */
fname++;
pat++;
break;
case FPAT_NOT:
/* Match only if rest of pattern does not match */
if (*pat == '\0')
return (FALSE); /* Missing subpattern */
i = fpattern_submatch(pat, fname);
return !i;
case DEL:
case DEL2:
/* Match path delimiter char */
if (fch != DEL && fch != DEL2)
return (FALSE);
fname++;
break;
default:
/* Match a (non-null) char exactly */
if (lowercase(fch) != lowercase(pch))
return (FALSE);
fname++;
break;
}
}
/* Check for complete match */
if (*fname != '\0')
return (FALSE);
/* Successful match */
return (TRUE);
}
/*-----------------------------------------------------------------------------
* fpattern_match()
* Attempts to match pattern 'pat' to filename 'fname'.
*
* Returns
* 1 (true) if the filename matches, otherwise 0 (false).
*
* Caveats
* If 'fname' is null, zero (false) is returned.
*
* If 'pat' is null, zero (false) is returned.
*
* If 'pat' is empty (""), the only filename it matches is the empty
* string ("").
*
* If 'fname' is empty, the only pattern that will match it is the empty
* string ("").
*
* If 'pat' is not a well-formed pattern, zero (false) is returned.
*
* Upper and lower case letters are treated the same; alphabetic
* characters are converted to lower case before matching occurs.
* Conversion to lower case is dependent upon the current locale setting.
*/
int CWild::fpattern_match(const char *pat, const char *fname)
{
int rc;
/* Check args */
if (fname == NULL)
return (FALSE);
if (pat == NULL)
return (FALSE);
/* Verify that the pattern is valid, and get its length */
if (!fpattern_isvalid(pat))
return (FALSE);
/* Attempt to match pattern against filename */
if (fname[0] == '\0')
return (pat[0] == '\0'); /* Special case */
rc = fpattern_submatch(pat, fname);
return (rc);
}
/*-----------------------------------------------------------------------------
* fpattern_matchn()
* Attempts to match pattern 'pat' to filename 'fname'.
* This operates like fpattern_match() except that it does not verify that
* pattern 'pat' is well-formed, assuming that it has been checked by a
* prior call to fpattern_isvalid().
*
* Returns
* 1 (true) if the filename matches, otherwise 0 (false).
*
* Caveats
* If 'fname' is null, zero (false) is returned.
*
* If 'pat' is null, zero (false) is returned.
*
* If 'pat' is empty (""), the only filename it matches is the empty ("")
* string.
*
* If 'pat' is not a well-formed pattern, unpredictable results may occur.
*
* Upper and lower case letters are treated the same; alphabetic
* characters are converted to lower case before matching occurs.
* Conversion to lower case is dependent upon the current locale setting.
*
* See also
* fpattern_match().
*/
int CWild::fpattern_matchn(const char *pat, const char *fname)
{
int rc;
/* Check args */
if (fname == NULL)
return (FALSE);
if (pat == NULL)
return (FALSE);
/* Assume that pattern is well-formed */
/* Attempt to match pattern against filename */
rc = fpattern_submatch(pat, fname);
return (rc);
}