- Added [:class:] handling to the character-class code.

- Use explicit unsigned characters for proper set checks.
- Made the character-class code honor backslash escapes.
- Accept '^' as a class-negation character in addition to '!'.
This commit is contained in:
Wayne Davison committed 2003-07-06 04:33:54 +00:00
1 parent 84229c7ac9
commit e11c425119
1 file changed
+52 -7
+52 -7
View File
@@ -12,21 +12,24 @@
#include "rsync.h"
/* What character marks an inverted character class? */
#define NEGATE_CLASS '!'
#define NEGATE_CLASS '!'
#define NEGATE_CLASS2 '^'
#define FALSE 0
#define TRUE 1
#define ABORT_ALL -1
#define ABORT_TO_STARSTAR -2
#define CC_EQ(class, len, litmatch) ((len) == sizeof (litmatch)-1 && strncmp(class, litmatch, len) == 0)
#ifdef WILD_TEST_ITERATIONS
int wildmatch_iteration_count;
#endif
static int domatch(const char *p, const char *text)
static int domatch(const unsigned char *p, const unsigned char *text)
{
int matched, special;
char ch, prev;
unsigned char ch, prev;
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count++;
@@ -73,6 +76,10 @@ static int domatch(const char *p, const char *text)
return ABORT_ALL;
case '[':
ch = *++p;
#ifdef NEGATE_CLASS2
if (ch == NEGATE_CLASS2)
ch = NEGATE_CLASS;
#endif
/* Assign literal TRUE/FALSE because of "matched" comparison. */
special = ch == NEGATE_CLASS? TRUE : FALSE;
if (special) {
@@ -84,9 +91,46 @@ static int domatch(const char *p, const char *text)
do {
if (!ch)
return FALSE;
if (ch == '-' && prev && p[1] && p[1] != ']') {
if (*text <= *++p && *text >= prev)
if (ch == '\\') {
ch = *++p;
if (!ch)
return FALSE;
if (*text == ch)
matched = TRUE;
}
else if (ch == '-' && prev && p[1] && p[1] != ']') {
ch = *++p;
if (ch == '\\') {
ch = *++p;
if (!ch)
return FALSE;
}
if (*text <= ch && *text >= prev)
matched = TRUE;
ch = 0; /* This makes "prev" get set to 0. */
}
else if (ch == '[' && p[1] == ':') {
unsigned const char *s = p += 2;
int i;
while ((ch = *p) && (ch != ':' || p[1] != ']')) p++;
if (!ch)
return FALSE;
i = p - s;
ch = *text;
if ((CC_EQ(s,i, "alnum") && isalnum(ch))
|| (CC_EQ(s,i, "alpha") && isalpha(ch))
|| (CC_EQ(s,i, "blank") && isblank(ch))
|| (CC_EQ(s,i, "cntrl") && iscntrl(ch))
|| (CC_EQ(s,i, "digit") && isdigit(ch))
|| (CC_EQ(s,i, "graph") && isgraph(ch))
|| (CC_EQ(s,i, "lower") && islower(ch))
|| (CC_EQ(s,i, "print") && isprint(ch))
|| (CC_EQ(s,i, "punct") && ispunct(ch))
|| (CC_EQ(s,i, "space") && isspace(ch))
|| (CC_EQ(s,i, "upper") && isupper(ch))
|| (CC_EQ(s,i,"xdigit") && isxdigit(ch)))
matched = TRUE;
p++;
ch = 0; /* This makes "prev" get set to 0. */
}
else if (*text == ch)
@@ -101,10 +145,11 @@ static int domatch(const char *p, const char *text)
return *text == '\0';
}
int wildmatch(const char *p, const char *text)
/* Find the pattern (p) in the text string (t). */
int wildmatch(const char *p, const char *t)
{
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count = 0;
#endif
return domatch(p, text) == TRUE;
return domatch((const unsigned char*)p, (const unsigned char*)t) == TRUE;
}