int matche (register char *p, register char *t) { register char range_start, range_end; /* start and end in range */ char invert; /* is this [..] or [!..] */ char member_match; /* have I matched the [..] construct? */ char loop; /* should I terminate? */ for ( ; *p; p++, t++) { /* if this is the end of the text then this is the end of the match */ if (!*t) { return ( *p == '*' && *++p == '\0' ) ? MATCH_VALID : MATCH_ABORT; } /* determine and react to pattern type */ switch (*p) { case '?': /* single any character match */ break; case '*': /* multiple any character match */ return matche_after_star (p, t); /* [..] construct, single member/exclusion character match */ case '[': { /* move to beginning of range */ p++; /* check if this is a member match or exclusion match */ invert = 0; if (*p == '!' || *p == '^') { invert = 1; p++; } /* if closing bracket here or at range start then we have a malformed pattern */ if (*p == ']') { return MATCH_PATTERN; } member_match = 0; loop = 1; while (loop) { /* if end of construct then loop is done */ if (*p == ']') { loop = 0; continue; } /* matching a '!', '^', '-', '\' or a ']' */ if (*p == '\\') { range_start = range_end = *++p; } else range_start = range_end = *p; /* if end of pattern then bad pattern (Missing ']') */ if (!*p) return MATCH_PATTERN; /* check for range bar */ if (*++p == '-') { /* get the range end */ range_end = *++p; /* if end of pattern or construct then bad pattern */ if (range_end == '\0' || range_end == ']') return MATCH_PATTERN; /* special character range end */ if (range_end == '\\') { range_end = *++p; /* if end of text then we have a bad pattern */ if (!range_end) return MATCH_PATTERN; } /* move just beyond this range */ p++; } /* if the text character is in range then match found. make sure the range letters have the proper relationship to one another before comparison */ if (range_start < range_end) { if (*t >= range_start && *t <= range_end) { member_match = 1; loop = 0; } } else { if (*t >= range_end && *t <= range_start) { member_match = 1; loop = 0; } } } /* if there was a match in an exclusion set then no match */ /* if there was no match in a member set then no match */ if ((invert && member_match) || !(invert || member_match)) return MATCH_RANGE; /* if this is not an exclusion then skip the rest of the [...] construct that already matched. */ if (member_match) { while (*p != ']') { /* bad pattern (Missing ']') */ if (!*p) return MATCH_PATTERN; /* skip exact match */ if (*p == '\\') { p++; /* if end of text then we have a bad pattern */ if (!*p) return MATCH_PATTERN; } /* move to next pattern char */ p++; } } break; } case '\\': /* next character is quoted and must match exactly */ /* move pattern pointer to quoted char and fall through */ p++; /* if end of text then we have a bad pattern */ if (!*p) return MATCH_PATTERN; /* must match this character exactly */ default: if (*p != *t) return MATCH_LITERAL; } } /* if end of text not reached then the pattern fails */ if (*t) return MATCH_END; else return MATCH_VALID; }
static int matche(register char *p, register char *t) { register char range_start, range_end; BOOLEAN invert; BOOLEAN member_match; BOOLEAN loop; for ( ; *p; p++, t++ ) { if (!*t) { return ( *p == '*' && *++p == '\0' ) ? MATCH_VALID : MATCH_ABORT; } switch ( *p ) { case '?': break; case '*': return matche_after_star (p, t); case '[': { p++; invert = FALSE; if ( *p == '!' || *p == '^') { invert = TRUE; p++; } if ( *p == ']' ) { return MATCH_PATTERN; } member_match = FALSE; loop = TRUE; while ( loop ) { if (*p == ']') { loop = FALSE; continue; } if ( *p == '\\' ) { range_start = range_end = *++p; } else { range_start = range_end = *p; } if (!*p) return MATCH_PATTERN; if (*++p == '-') { range_end = *++p; if (range_end == '\0' || range_end == ']') return MATCH_PATTERN; if (range_end == '\\') { range_end = *++p; if (!range_end) return MATCH_PATTERN; } p++; } if ( range_start < range_end ) { if (*t >= range_start && *t <= range_end) { member_match = TRUE; loop = FALSE; } } else { if (*t >= range_end && *t <= range_start) { member_match = TRUE; loop = FALSE; } } } if ((invert && member_match) || !(invert || member_match)) return MATCH_RANGE; if (member_match) { while (*p != ']') { if (!*p) return MATCH_PATTERN; if (*p == '\\') { p++; if (!*p) return MATCH_PATTERN; } p++; } } break; } default: if (*p != *t) return MATCH_LITERAL; } } if ( *t ) return MATCH_END; else return MATCH_VALID; }