Path: utzoo!attcan!uunet!munnari.oz.au!uniwa!DIALix!metapro!bernie From: bernie@metapro.DIALix.oz.au (Bernd Felsche) Newsgroups: comp.unix.shell Subject: Re: PD file-globbing code? Message-ID: <1991Feb8.094129.802@metapro.DIALix.oz.au> Date: 8 Feb 91 09:41:29 GMT References: <1991Feb6.081556.25915@parc.xerox.com> Organization: MetaPro Systems, Perth, Western Australia Lines: 122 In <1991Feb6.081556.25915@parc.xerox.com> janssen@parc.xerox.com (Bill Janssen) writes: >Anyone have a nice bit of file-globbing code that can be freely used >by others? That in csh, sh, ksh, tcsh, and bash doesn't seem to >qualify... I recently posted this to alt.sources.something. It's from Rich Salz's wildmat routine. Some problems have been fixed, including the "not" operator, trailing "*" handling, and a few other bits and pieces. This is NOT a shell archive. ---------------cut along here with glass cutter--------------- /* ** Do shell-style pattern matching for ?, \, [], and * characters. ** Might not be robust in face of malformed patterns; e.g., "foo[a-" ** could cause a segmentation violation. It is 8bit clean. ** ** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986. ** Special thanks to Lars Mathiesen for the ABORT code. This can greatly ** speed up failing wildcard patterns. For example: ** pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-* ** text 1: -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1 ** text 2: -adobe-courier-bold-o-normal--12-120-75-75-p-70-iso8859-1 ** Text 1 matches with 51 calls, while text 2 fails with 54 calls. Without ** the ABORT, then it takes 22310 calls to fail. Ugh. ** ** bernie 613-01 91/01/04 19:34 ** Fixed problem with terminating * not matching with (null) ** ** bernie 597-00 91/01/08 11:24 ** Fixed shell glob negate from '^' to '!' ** ** bernie 597-02 91/01/21 13:43 ** Fixed . matching * or ? on first char. */ #define TRUE 1 #define FALSE 0 #define ABORT -1 static int Star(s, p) register char *s; register char *p; { while (DoMatch(s, p) == FALSE) /* gobble up * match */ if (*++s == '\0') return ABORT; return TRUE; } static int DoMatch(s, p) /* match string "s" to pattern "p" */ register char *s; register char *p; { register int last; register int matched; register int reverse; for ( ; *p; s++, p++) { /* parse the string to end */ if (*s == '\0') return *p == '*' && *++p == '\0' ? TRUE : ABORT; switch (*p) { /* parse pattern */ case '\\': /* Literal match with following character. */ p++; /* FALLTHROUGH */ default: /*literal match*/ if (*s != *p) return FALSE; continue; case '?': /* Match anything. */ continue; case '*': /* Trailing star matches everything. */ return( *++p ? Star(s, p) : TRUE ); case '[': /* [!....] means inverse character class. */ if (reverse = p[1] == '!') p++; for (last = 0400, matched = FALSE; *++p && *p != ']'; last = *p) /* This next line requires a good C compiler. */ /* range? (in bounds) (equal) */ if ( ( *p == '-' ) ? (*s <= *++p && *s >= last ) : (*s == *p) ) matched = TRUE; if (matched == reverse) return FALSE; continue; } } return *s == '\0'; } int wildmat(s, p) char *s; char *p; { if ( (*p == '?' || *p == '*' ) && *s == '.' ) { return FALSE; } else { return DoMatch(s, p) == TRUE; } } ---------------------the end--------------------------- -- _--_|\ Bernd Felsche #include / \ Metapro Systems, 328 Albany Highway, Victoria Park, Western Australia \_.--._/ Fax: +61 9 472 3337 Phone: +61 9 362 9355 TZ=WST-8 v E-Mail: bernie@metapro.DIALix.oz.au | bernie@DIALix.oz.au Brought to you by Super Global Mega Corp .com