2 ** Do shell-style pattern matching for ?, \, [], and * characters.
5 ** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
6 ** Rich $alz is now <rsalz@bbn.com>.
8 ** Modified by Wayne Davison to special-case '/' matching, to make '**'
9 ** work differently than '*', and to fix the character-class code.
14 /* What character marks an inverted character class? */
15 #define NEGATE_CLASS '!'
20 #define ABORT_TO_STARSTAR -2
22 #ifdef WILD_TEST_ITERATIONS
23 int wildmatch_iteration_count;
26 static int domatch(const char *p, const char *text)
31 #ifdef WILD_TEST_ITERATIONS
32 wildmatch_iteration_count++;
35 for ( ; (ch = *p) != '\0'; text++, p++) {
36 if (*text == '\0' && ch != '*')
40 /* Literal match with following character. Note that the test
41 * in "default" handles the p[1] == '\0' failure case. */
49 /* Match anything but '/'. */
55 while (*++p == '*') {}
61 /* Trailing "**" matches everything. Trailing "*" matches
62 * only if there are no more slash characters. */
63 return special? TRUE : strchr(text, '/') == NULL;
65 for ( ; *text; text++) {
66 if ((matched = domatch(p, text)) != FALSE) {
67 if (!special || matched != ABORT_TO_STARSTAR)
70 else if (!special && *text == '/')
71 return ABORT_TO_STARSTAR;
76 /* Assign literal TRUE/FALSE because of "matched" comparison. */
77 special = ch == NEGATE_CLASS? TRUE : FALSE;
79 /* Inverted character class. */
87 if (ch == '-' && prev && p[1] && p[1] != ']') {
88 if (*text <= *++p && *text >= prev)
90 ch = 0; /* This makes "prev" get set to 0. */
94 } while (prev = ch, (ch = *++p) != ']');
95 if (matched == special)
101 return *text == '\0';
104 int wildmatch(const char *p, const char *text)
106 #ifdef WILD_TEST_ITERATIONS
107 wildmatch_iteration_count = 0;
109 return domatch(p, text) == TRUE;