home *** CD-ROM | disk | FTP | other *** search
- /*
- ** 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.
- */
-
- #define TRUE 1
- #define FALSE 0
- #define ABORT -1
-
- static int
- Star(s, p)
- register char *s;
- register char *p;
- {
- while (wildmat(s, p) == FALSE)
- if (*++s == '\0')
- return ABORT;
- return TRUE;
- }
-
-
- static int
- DoMatch(s, p)
- register char *s;
- register char *p;
- {
- register int last;
- register int matched;
- register int reverse;
-
- for ( ; *p; s++, p++) {
- if (*s == '\0')
- return ABORT;
- switch (*p) {
- case '\\':
- /* Literal match with following character. */
- p++;
- /* FALLTHROUGH */
- default:
- 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. */
- 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;
- {
- return DoMatch(s, p) == TRUE;
- }
-
-
-
- #ifdef TEST
- #include <stdio.h>
-
- /* Yes, we use gets not fgets. Sue me. */
- extern char *gets();
-
-
- main()
- {
- char pattern[80];
- char text[80];
-
- printf("Wildmat tester. Enter pattern, then strings to test.\n");
- printf("A blank line gets prompts for a new pattern; a blank pattern\n");
- printf("exits the program.\n\n");
-
- for ( ; ; ) {
- printf("Enter pattern: ");
- if (gets(pattern) == NULL)
- break;
- for ( ; ; ) {
- printf("Enter text: ");
- if (gets(text) == NULL)
- exit(0);
- if (text[0] == '\0')
- /* Blank line; go back and get a new pattern. */
- break;
- printf(" %s\n", wildmat(text, pattern) ? "YES" : "NO");
- }
- }
-
- exit(0);
- /* NOTREACHED */
- }
- #endif /* TEST */
-