Str_Matchi(string, pattern, end)
Str_Matchi(string, estring, pattern, end)
Str_Matchi(string, pattern, end)    const char *string; 		/* String */    const char *pattern;		/* Pattern */    const char *end;			/* End of Pattern */{    while (pattern != end) {	/* 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++;	    /* Skip over contiguous  sequences of `?*', so that recursive	     * calls only occur on `real' characters.  */	    while (pattern != end && (*pattern == '?' || *pattern == '*')) {		if (*pattern == '?') {		    if (*string == '\0')			return FALSE;		    else			string++;		}		pattern++;	    }	    if (pattern == end)		return TRUE;	    for (; *string != '\0'; string++)		if (Str_Matchi(string, pattern, end))		    return TRUE;	    return FALSE;	} else if (*string == '\0')	    return FALSE;	/* 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 "-").  */	else if (*pattern == '[') {	    pattern++;	    if (pattern == end)		return FALSE;	    if (*pattern == '!' || *pattern == '^') {		pattern++;		if (pattern == end)			return FALSE;		/* Negative match */		for (;;) {		    if (*pattern == '\\') {			if (++pattern == end)			    return FALSE;		    }		    if (*pattern == *string)			return FALSE;		    if (pattern[1] == '-') {			if (pattern + 2 == end)			    return FALSE;			if (*pattern < *string && *string <= pattern[2])			    return FALSE;			if (pattern[2] <= *string && *string < *pattern)			    return FALSE;			pattern += 3;		    } else			pattern++;		    if (pattern == end)			return FALSE;		    /* The test for ']' is done at the end so that ']'		     * can be used at the start of the range without '\' */		    if (*pattern == ']')			break;		}	    } else {		for (;;) {		    if (*pattern == '\\') {			if (++pattern == end)			    return FALSE;		    }		    if (*pattern == *string)			break;		    if (pattern[1] == '-') {			if (pattern + 2 == end)			    return FALSE;			if (*pattern < *string && *string <= pattern[2])			    break;			if (pattern[2] <= *string && *string < *pattern)			    break;			pattern += 3;		    } else			pattern++;		    /* The test for ']' is done at the end so that ']'		     * can be used at the start of the range without '\' */		    if (pattern == end || *pattern == ']')			return FALSE;		}		/* Found matching character, skip over rest of class.  */		while (*pattern != ']') {		    if (*pattern == '\\')			pattern++;		    /* A non-terminated character class is ok.	*/		    if (pattern == end)			break;		    pattern++;		}	    }	}	/* '?' matches any single character, so shunt test.  */	else if (*pattern != '?') {	    /* If the next pattern character is '\', just strip off the	     * '\' so we do exact matching on the character that follows.  */	    if (*pattern == '\\') {		if (++pattern == end)		    return FALSE;	    }	    /* There's no special character.  Just make sure that	     * the next characters of each string match.  */	    if (*pattern != *string)		return FALSE;	}	pattern++;	string++;    }    if (*string == '\0')	return TRUE;    else	return FALSE;}