/* =========================================================================== * Recursively compare the sh pattern p, with the string s, * and return 1 if they match, and 0 or 2 if they don't (or if * there is a syntax error in the pattern). This routine * recurses on itself no deeper than the number of characters * in the pattern. *p :: sh pattern to match (ex: *.*). *s :: String to match it to (ex: FNAME.DAT). */ static int recmatch( uch *p, uch *s, struct Globals *pG ) { unsigned int c; /* pattern char or start of range in [-] loop */ /* Get first character, the pattern for new recmatch calls follows */ c = *p++; /* If that was the end of the pattern, match if string empty too */ if ( c == 0 ) return *s == 0; /* '?' matches any character (but not an empty string) */ if ( c == '?' ) return *s ? recmatch( p, s + 1, pG ) : 0; /* '*' matches any number of characters, including no char's! */ /* EWE: todo: for MS-DOS/Win make sure it won't match period! */ if ( c == '*' ) { if ( *p == 0 ) return 1; for ( ; *s; s++ ) if ( (c = recmatch( p, s, pG )) != 0 ) return (int)c; return 2; /* 2 means give up -- shmatch will return false */ } /* if escape ('\'), just compare next character */ // if ( c == '\\' ) if ( (c = *p++) == 0 ) /* if \ at end, then syntax error */ // return 0; /* Just a character--compare it */ return case_map( c ) == case_map( *s ) ? recmatch( p, ++s, pG ) : 0; }
// Slow version, used if caller hasn't stored an upper and lower case version bool operator()(StringData v1, StringData v2, bool = false, bool = false) const { if (v1.is_null() != v2.is_null()) return true; if (v1.size() != v2.size()) return true; std::string v1_upper = case_map(v1, true); std::string v1_lower = case_map(v1, false); return !equal_case_fold(v2, v1_upper.c_str(), v1_lower.c_str()); }
// Slow version, used if caller hasn't stored an upper and lower case version bool operator()(StringData v1, StringData v2, bool = false, bool = false) const { if (v2.is_null() && !v1.is_null()) return false; if (v1.size() > v2.size()) return false; std::string v1_upper = case_map(v1, true, IgnoreErrors); std::string v1_lower = case_map(v1, false, IgnoreErrors); return equal_case_fold(v2.suffix(v1.size()), v1_upper.c_str(), v1_lower.c_str()); }
// Slow version, used if caller hasn't stored an upper and lower case version bool operator()(StringData v1, StringData v2, bool = false, bool = false) const { if (v2.is_null() && !v1.is_null()) return false; if (v1.size() == 0 && !v2.is_null()) return true; std::string v1_upper = case_map(v1, true, IgnoreErrors); std::string v1_lower = case_map(v1, false, IgnoreErrors); return search_case_fold(v2, v1_upper.c_str(), v1_lower.c_str(), v1.size()) != v2.size(); }
/* =========================================================================== * Compare the two strings ignoring case, and correctly taking into * account national language characters. * If equal return 0 else != 0. */ int namecmp( char *string1, char *string2 ) { int Error; struct Globals *pG = GetGlobalPointer( &Error ); if ( pG ) for (;;) { int d = (int)(uch)case_map( *string1 ) - (int)(uch)case_map( *string2 ); if ( d || *string1 == 0 || *string2 == 0 ) return d; string1++; string2++; } return 1; }
local int recmatch(ZCONST uch *p, ZCONST uch *s, int cs) //ZCONST uch *p; /* sh pattern to match */ //ZCONST uch *s; /* string to match it to */ //int cs; /* flag: force case-sensitive matching */ /* Recursively compare the sh pattern p with the string s and return 1 if they match, and 0 or 2 if they don't or if there is a syntax error in the pattern. This routine recurses on itself no deeper than the number of characters in the pattern. */ { unsigned int c; /* pattern char or start of range in [-] loop */ /* Get first character, the pattern for new recmatch calls follows */ c = *POSTINCSTR(p); /* If that was the end of the pattern, match if string empty too */ if (c == 0) return *s == 0; /* '?' (or '%' or '#') matches any character (but not an empty string) */ #ifdef VMS if (c == '%') #else /* !VMS */ # ifdef RISCOS if (c == '#') # else /* !RISC OS */ if (c == '?') # endif #endif /* ?VMS */ #ifdef WILD_STOP_AT_DIR return (*s && *s != '/') ? recmatch(p, s + CLEN(s), cs) : 0; #else return *s ? recmatch(p, s + CLEN(s), cs) : 0; #endif /* '*' matches any number of characters, including zero */ #ifdef AMIGA if (c == '#' && *p == '?') /* "#?" is Amiga-ese for "*" */ c = '*', p++; #endif /* AMIGA */ if (c == '*') { if (*p == 0) return 1; #ifdef WILD_STOP_AT_DIR for (; *s && *s != '/'; INCSTR(s)) if ((c = recmatch(p, s, cs)) != 0) return (int)c; return (*p == '/' || (*p == '\\' && p[1] == '/')) ? recmatch(p, s, cs) : 2; #else /* !WILD_STOP_AT_DIR */ for (; *s; INCSTR(s)) if ((c = recmatch(p, s, cs)) != 0) return (int)c; return 2; /* 2 means give up--shmatch will return false */ #endif /* ?WILD_STOP_AT_DIR */ } #ifndef VMS /* No bracket matching in VMS */ /* Parse and process the list of characters and ranges in brackets */ if (c == '[') { int e; /* flag true if next char to be taken literally */ ZCONST uch *q; /* pointer to end of [-] group */ int r; /* flag true to match anything but the range */ if (*s == 0) /* need a character to match */ return 0; p += (r = (*p == '!' || *p == '^')); /* see if reverse */ for (q = p, e = 0; *q; q++) /* find closing bracket */ if (e) e = 0; else if (*q == '\\') e = 1; else if (*q == ']') break; if (*q != ']') /* nothing matches if bad syntax */ return 0; for (c = 0, e = *p == '-'; p < q; p++) /* go through the list */ { if (e == 0 && *p == '\\') /* set escape flag if \ */ e = 1; else if (e == 0 && *p == '-') /* set start of range if - */ c = *(p-1); else { uch cc = (cs ? *s : case_map(*s)); if (*(p+1) != '-') for (c = c ? c : (unsigned)*p; c <= (unsigned)*p; c++) /* compare range */ if ((cs ? c : case_map(c)) == cc) return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), cs); c = e = 0; /* clear range, escape flags */ } } return r ? recmatch(q + CLEN(q), s + CLEN(s), cs) : 0; /* bracket match failed */ } #endif /* !VMS */ /* If escape ('\'), just compare next character */ if (c == '\\') if ((c = *p++) == '\0') /* if \ at end, then syntax error */ return 0; /* Just a character--compare it */ return (cs ? c == *s : case_map(c) == case_map(*s)) ? recmatch(p, s + CLEN(s), cs) : 0; }