This is lib_string.c in view mode; [Download] [Up]
#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++; } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.