mirror of
https://github.com/TTimo/GtkRadiant.git
synced 2025-01-25 02:41:22 +00:00
caabb8dceb
* 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
338 lines
6.6 KiB
C++
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);
|
|
}
|