|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Guido van Rossum. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted provided ! 9: * that: (1) source distributions retain this entire copyright notice and ! 10: * comment, and (2) distributions including binaries display the following ! 11: * acknowledgement: ``This product includes software developed by the ! 12: * University of California, Berkeley and its contributors'' in the ! 13: * documentation or other materials provided with the distribution and in ! 14: * all advertising materials mentioning features or use of this software. ! 15: * Neither the name of the University nor the names of its contributors may ! 16: * be used to endorse or promote products derived from this software without ! 17: * specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #if defined(LIBC_SCCS) && !defined(lint) ! 24: static char sccsid[] = "@(#)fnmatch.c 5.3 (Berkeley) 6/23/90"; ! 25: #endif /* LIBC_SCCS and not lint */ ! 26: ! 27: /* ! 28: * Function fnmatch() as proposed in Posix 1003.2 B.6 (rev. 9). ! 29: * Compares a filename or pathname to a pattern. ! 30: */ ! 31: ! 32: #include <unistd.h> ! 33: #include <string.h> ! 34: ! 35: #define EOS '\0' ! 36: ! 37: static char * ! 38: rangematch(pattern, test) ! 39: register char *pattern, test; ! 40: { ! 41: register char c, c2; ! 42: int negate, ok; ! 43: ! 44: if (negate = (*pattern == '!')) ! 45: ++pattern; ! 46: ! 47: /* ! 48: * TO DO: quoting ! 49: */ ! 50: ! 51: for (ok = 0; (c = *pattern++) != ']';) { ! 52: if (c == EOS) ! 53: return(NULL); /* illegal pattern */ ! 54: if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']') { ! 55: if (c <= test && test <= c2) ! 56: ok = 1; ! 57: pattern += 2; ! 58: } ! 59: else if (c == test) ! 60: ok = 1; ! 61: } ! 62: return(ok == negate ? NULL : pattern); ! 63: } ! 64: ! 65: fnmatch(pattern, string, flags) ! 66: register char *pattern, *string; ! 67: int flags; ! 68: { ! 69: register char c; ! 70: char test, *rangematch(); ! 71: ! 72: for (;;) ! 73: switch (c = *pattern++) { ! 74: case EOS: ! 75: return(*string == EOS); ! 76: case '?': ! 77: if ((test = *string++) == EOS || ! 78: test == '/' && flags & FNM_PATHNAME) ! 79: return(0); ! 80: break; ! 81: case '*': ! 82: c = *pattern; ! 83: /* collapse multiple stars */ ! 84: while (c == '*') ! 85: c = *++pattern; ! 86: ! 87: /* optimize for pattern with * at end or before / */ ! 88: if (c == EOS) ! 89: if (flags & FNM_PATHNAME) ! 90: return(!index(string, '/')); ! 91: else ! 92: return(1); ! 93: else if (c == '/' && flags & FNM_PATHNAME) { ! 94: if ((string = index(string, '/')) == NULL) ! 95: return(0); ! 96: break; ! 97: } ! 98: ! 99: /* general case, use recursion */ ! 100: while ((test = *string) != EOS) { ! 101: if (fnmatch(pattern, string, flags)) ! 102: return(1); ! 103: if (test == '/' && flags & FNM_PATHNAME) ! 104: break; ! 105: ++string; ! 106: } ! 107: return(0); ! 108: case '[': ! 109: if ((test = *string++) == EOS || ! 110: test == '/' && flags & FNM_PATHNAME) ! 111: return(0); ! 112: if ((pattern = rangematch(pattern, test)) == NULL) ! 113: return(0); ! 114: break; ! 115: case '\\': ! 116: if (flags & FNM_QUOTE) { ! 117: if ((c = *pattern++) == EOS) { ! 118: c = '\\'; ! 119: --pattern; ! 120: } ! 121: if (c != *string++) ! 122: return(0); ! 123: break; ! 124: } ! 125: /* FALLTHROUGH */ ! 126: default: ! 127: if (c != *string++) ! 128: return(0); ! 129: break; ! 130: } ! 131: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.