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.