home *** CD-ROM | disk | FTP | other *** search
- From: bernie@metapro.DIALix.oz.au (Bernd Felsche)
- Newsgroups: alt.sources
- Subject: Repost: Shell-style wildcard matching
- Message-ID: <1991Jan29.041342.26733@metapro.DIALix.oz.au>
- Date: 29 Jan 91 04:13:42 GMT
-
- [ Sorry to those of you who are seeing this again, but I think this got ]
- [ zapped somewhere, on its way to the real world. (no flames or comment)]
-
- Thanks mainly to Rich Salz, we now have a useful shell-style
- wildcard matching routine. It took a little bashing to make it
- behave the same way as the Bourne shell (and Korn shell).
-
- This posting is without the permission of Rich, though I'm sure he
- won't mind, as it fixes a few problems that have been unearthed.
-
- Remember, UTSL.
-
- --------------------cut here if you're brave----------------
- #!/bin/sh
- # manually shar'ed, so don't complain, all right?
- # at the end of this shar you should seen the message
- # "wildmat.c complete".
- #
- # Here's shar!
- if test -f wildmat.c
- then
- echo wildmat.c exists, won\'t clobber.
- exit 1
- fi
- echo extracting wildmat.c
- sed 's/^X//' > wildmat.c << 'SHAR_EOF' &&
- X/*
- X** Do shell-style pattern matching for ?, \, [], and * characters.
- X** Might not be robust in face of malformed patterns; e.g., "foo[a-"
- X** could cause a segmentation violation. It is 8bit clean.
- X**
- X** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
- X** Special thanks to Lars Mathiesen for the ABORT code. This can greatly
- X** speed up failing wildcard patterns. For example:
- X** pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-*
- X** text 1: -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1
- X** text 2: -adobe-courier-bold-o-normal--12-120-75-75-p-70-iso8859-1
- X** Text 1 matches with 51 calls, while text 2 fails with 54 calls. Without
- X** the ABORT, then it takes 22310 calls to fail. Ugh.
- X**
- X** bernie 613-01 91/01/04 19:34
- X** Fixed problem with terminating * not matching with (null)
- X**
- X** bernie 597-00 91/01/08 11:24
- X** Fixed shell glob negate from '^' to '!'
- X**
- X** bernie 597-02 91/01/21 13:43
- X** Fixed . matching * or ? on first char.
- X*/
- X
- X#define TRUE 1
- X#define FALSE 0
- X#define ABORT -1
- X
- Xstatic int
- XStar(s, p)
- X register char *s;
- X register char *p;
- X{
- X while (DoMatch(s, p) == FALSE) /* gobble up * match */
- X if (*++s == '\0') return ABORT;
- X return TRUE;
- X}
- X
- X
- Xstatic int
- XDoMatch(s, p) /* match string "s" to pattern "p" */
- X register char *s;
- X register char *p;
- X{
- X register int last;
- X register int matched;
- X register int reverse;
- X
- X for ( ; *p; s++, p++) { /* parse the string to end */
- X
- X if (*s == '\0')
- X return *p == '*' && *++p == '\0' ? TRUE : ABORT;
- X
- X switch (*p) { /* parse pattern */
- X
- X case '\\':
- X /* Literal match with following character. */
- X p++;
- X /* FALLTHROUGH */
- X
- X default: /*literal match*/
- X if (*s != *p)
- X return FALSE;
- X continue;
- X
- X case '?':
- X /* Match anything. */
- X continue;
- X
- X case '*':
- X /* Trailing star matches everything. */
- X return( *++p ? Star(s, p) : TRUE );
- X
- X case '[':
- X /* [!....] means inverse character class. */
- X if (reverse = p[1] == '!') p++;
- X
- X for (last = 0400, matched = FALSE; *++p && *p != ']'; last = *p)
- X /* This next line requires a good C compiler. */
- X /* range? (in bounds) (equal) */
- X if ( ( *p == '-' ) ? (*s <= *++p && *s >= last ) : (*s == *p) )
- X matched = TRUE;
- X
- X if (matched == reverse) return FALSE;
- X continue;
- X
- X }
- X }
- X
- X return *s == '\0';
- X}
- X
- X
- Xint wildmat(s, p)
- X char *s;
- X char *p;
- X{
- X if ( (*p == '?' || *p == '*' ) && *s == '.' ) {
- X return FALSE;
- X } else {
- X return DoMatch(s, p) == TRUE;
- X }
- X}
- SHAR_EOF
- chmod 0644 wildmat.c ||
- echo extract failed - squezze it yourself!
- if test `wc -c < wildmat.c` -ne 2524
- then
- echo possible file size error with wildmat.c
- exit 2
- fi
- echo "wildmat.c complete"
-
- exit # because you shouldn't execute my signature
- --
- _--_|\ 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@metapro.DIALix.oz.au | bernie@DIALix.oz.au
-