PD file-globbing code?
Bernd Felsche
bernie at metapro.DIALix.oz.au
Fri Feb 8 20:41:29 AEST 1991
In <1991Feb6.081556.25915 at parc.xerox.com> janssen at 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 <std/disclaimer.h>
/ \ 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 at metapro.DIALix.oz.au | bernie at DIALix.oz.au
More information about the Comp.unix.shell
mailing list