int fnmatch(const char *pattern, const char *string, int flags) { char c; char test; for (;;) switch ((c = *pattern++)) { case 0: return *string == 0 ? 0 : FNM_NOMATCH; case '?': if ((test = *string++) == 0 || (isslash(test) && (flags & FNM_PATHNAME))) return(FNM_NOMATCH); break; case '*': c = *pattern; /* collapse multiple stars */ while (c == '*') c = *++pattern; /* optimize for pattern with * at end or before / */ if (c == 0) { if (flags & FNM_PATHNAME) return find_slash(string) ? FNM_NOMATCH : 0; else return 0; } else if (isslash(c) && flags & FNM_PATHNAME) { if ((string = find_slash(string)) == NULL) return FNM_NOMATCH; break; } /* general case, use recursion */ while ((test = *string) != 0) { if (fnmatch(pattern, string, flags) == 0) return(0); if (isslash(test) && flags & FNM_PATHNAME) break; ++string; } return FNM_NOMATCH; case '[': if ((test = *string++) == 0 || (isslash(test) && flags & FNM_PATHNAME)) return FNM_NOMATCH; if ((pattern = rangematch(pattern, test, flags & FNM_NOCASE)) == NULL) return FNM_NOMATCH; break; case '\\': if (!(flags & FNM_NOESCAPE) && pattern[1] && strchr("*?[\\", pattern[1])) { if ((c = *pattern++) == 0) { c = '\\'; --pattern; } if (c != *string++) return FNM_NOMATCH; break; } /* FALLTHROUGH */ default: if (isslash(c) && isslash(*string)) { string++; break; } if (flags & FNM_NOCASE) { if (toupper(c) != toupper(*string++)) return FNM_NOMATCH; } else { if (c != *string++) return FNM_NOMATCH; } break; } }
static String find_slash(String str) { int n; if (MB_CUR_MAX == 1) { return strchr(str, '/'); } else { #ifndef NO_MULTIBYTE while ((n = mblen(str, MB_CUR_MAX)) >0) { #else if (!str) return NULL; while ((n = *str ? 1 : 0) > 0) { #endif #ifndef NO_MULTIBYTE if (n == 1 && *str == '/') return str; str += n; #else if (*str == '/') return str; str++; #endif } return NULL; } } static Boolean TestIconFile(String path) { struct stat status; int dirCacheType; if (!path || !*path) return False; /* if there is no directory information in the name, it's a local file, check here or CheckDirCache will fail */ if (!find_slash(path)) { dirCacheType = DtUNCACHED_DIR ; #ifndef XTHREADS GleafName = path ; GdirName = "." ; #endif } else dirCacheType = CheckDirCache(path); switch(dirCacheType) { case DtVALID_CACHED_DIR: return True; case DtINVALID_CACHED_DIR: return False; case DtUNCACHED_DIR: return (access(path, R_OK) == 0 && /* exists and is readable */ stat(path, &status) == 0 && /* get the status */ S_ISDIR(status.st_mode) == 0 /* not a directory */ ); } return False ; } /*********** Hash table stuff */ typedef struct _DtIconNameEntryRec{ String dirName; String leafName; String key_name; }DtIconNameEntryRec, *DtIconNameEntry; /* Compare two icon names from icon entry rec */ static Boolean CompareIconNames (XmHashKey key_1, XmHashKey key_2) { DtIconNameEntry data_1 = (DtIconNameEntry) key_1; DtIconNameEntry data_2 = (DtIconNameEntry) key_2; return ((data_1->key_name == data_2->key_name) || (strcmp(data_1->key_name, data_2->key_name) == 0)); }
int fnmatch (const char *pattern, const char *string, int flags) { char c, test; while (1) { c = *pattern++; switch (c) { case 0: return (*string == 0 ? FNM_MATCH : FNM_NOMATCH); case '?': test = *string++; if (test == 0 || (IS_SLASH(test) && (flags & FNM_FLAG_PATHNAME))) return (FNM_NOMATCH); break; case '*': c = *pattern; /* collapse multiple stars */ while (c == '*') c = *(++pattern); /* optimize for pattern with '*' at end or before '/' */ if (c == 0) { if (flags & FNM_FLAG_PATHNAME) return (find_slash(string) ? FNM_NOMATCH : FNM_MATCH); return (FNM_MATCH); } if (IS_SLASH(c) && (flags & FNM_FLAG_PATHNAME)) { string = find_slash (string); if (!string) return (FNM_NOMATCH); break; } /* general case, use recursion */ while ((test = *string) != '\0') { if (fnmatch(pattern, string, flags) == FNM_MATCH) return (FNM_MATCH); if (IS_SLASH(test) && (flags & FNM_FLAG_PATHNAME)) break; ++string; } return (FNM_NOMATCH); case '[': test = *string++; if (!test || (IS_SLASH(test) && (flags & FNM_FLAG_PATHNAME))) return (FNM_NOMATCH); pattern = range_match (pattern, test, flags & FNM_FLAG_NOCASE); if (!pattern) return (FNM_NOMATCH); break; case '\\': if (!(flags & FNM_FLAG_NOESCAPE) && pattern[1] && strchr("*?[\\", pattern[1])) { c = *pattern++; if (c == 0) { c = '\\'; --pattern; } if (c != *string++) return (FNM_NOMATCH); break; } /* FALLTHROUGH */ default: if (IS_SLASH(c) && IS_SLASH(*string)) { string++; break; } if (flags & FNM_FLAG_NOCASE) { if (TOUPPER(c) != TOUPPER(*string++)) return (FNM_NOMATCH); } else { if (c != *string++) return (FNM_NOMATCH); } break; } /* switch (c) */ } /* while (1) */ }