home *** CD-ROM | disk | FTP | other *** search
- #define FALSE 0
- #define TRUE 1
-
- /* The following functions implement expect's glob-style string matching */
- /* Exp_StringMatch allow's implements the unanchored front (or conversely */
- /* the '^') feature. Exp_StringMatch2 does the rest of the work. */
- int /* returns # of chars that matched */
- Exp_StringMatch(string, pattern,offset)
- char *string;
- char *pattern;
- int *offset; /* offset from beginning of string where pattern matches */
- {
- char *s;
- int sm; /* count of chars matched or -1 */
- int caret = FALSE;
-
- *offset = 0;
-
- if (pattern[0] == '^') {
- caret = TRUE;
- pattern++;
- }
-
- sm = Exp_StringMatch2(string,pattern);
- if (sm >= 0) return(sm);
-
- if (caret) return(-1);
-
- if (pattern[0] == '*') return(-1);
-
- for (s = string;*s;s++) {
- sm = Exp_StringMatch2(s,pattern);
- if (sm != -1) {
- *offset = s-string;
- return(sm);
- }
- }
- return(-1);
- }
-
- /* Exp_StringMatch2 --
-
- Like Tcl_StringMatch except that
- 1) returns number of characters matched, -1 if failed.
- (Can return 0 on patterns like "" or "$")
- 2) does not require pattern to match to end of string
- 3) Original code is stolen from Tcl_StringMatch
- */
-
- int Exp_StringMatch2(string,pattern)
- register char *string; /* String. */
- register char *pattern; /* Pattern, which may contain
- * special characters. */
- {
- char c2;
- int match = 0; /* # of chars matched */
-
- while (1) {
- /* See if we're at the end of both the pattern and the string.
- * If so, we succeeded. If we're at the end of the pattern
- * but not at the end of the string, we failed.
- */
-
- if (*pattern == 0) {
- /* removed test for end of string - DEL */
- return match;
- }
-
- if ((*string == 0) && (*pattern != '*')) {
- return -1;
- }
-
- /* Check for a "*" as the next pattern character. It matches
- * any substring. We handle this by calling ourselves
- * recursively for each postfix of string, until either we
- * match or we reach the end of the string.
- */
-
- if (*pattern == '*') {
- pattern += 1;
- if (*pattern == 0) {
- return(strlen(string)+match); /* DEL */
- }
- while (*string != 0) {
- int rc; /* DEL */
-
- if (-1 != (rc = Exp_StringMatch2(string, pattern))) {
- return rc+match; /* DEL */
- }
- string += 1;
- match++; /* DEL */
- }
- if (*pattern == '$') return 0; /* handle *$ */
- return -1; /* DEL */
- }
-
- /* Check for a "?" as the next pattern character. It matches
- * any single character.
- */
-
- if (*pattern == '?') {
- goto thisCharOK;
- }
-
- /* Check for a "[" as the next pattern character. It is followed
- * by a list of characters that are acceptable, or by a range
- * (two characters separated by "-").
- */
-
- if (*pattern == '[') {
- pattern += 1;
- while (1) {
- if ((*pattern == ']') || (*pattern == 0)) {
- return 0;
- }
- if (*pattern == *string) {
- break;
- }
- if (pattern[1] == '-') {
- c2 = pattern[2];
- if (c2 == 0) {
- return -1; /* DEL */
- }
- if ((*pattern <= *string) && (c2 >= *string)) {
- break;
- }
- if ((*pattern >= *string) && (c2 <= *string)) {
- break;
- }
- pattern += 2;
- }
- pattern += 1;
- }
- while ((*pattern != ']') && (*pattern != 0)) {
- pattern += 1;
- }
- goto thisCharOK;
- }
-
- /* If the last pattern character is '$', verify that the entire
- * string has been matched. - DEL
- */
-
- if ((*pattern == '$') && (pattern[1] == 0)) {
- if (*string == 0) return(0);
- else return(-1);
- }
-
- /* If the next pattern character is '/', just strip off the '/'
- * so we do exact matching on the character that follows.
- */
-
- if (*pattern == '\\') {
- pattern += 1;
- if (*pattern == 0) {
- return -1;
- }
- }
-
- /* There's no special character. Just make sure that the next
- * characters of each string match.
- */
-
- if (*pattern != *string) {
- return -1;
- }
-
- thisCharOK: pattern += 1;
- string += 1;
- match++;
- }
- }
-