pattern/wild card matching
Karl Heuer
karl at ima.isc.com
Wed Feb 13 13:35:48 AEST 1991
In answer to the question:
>where I can find such for the pattern/wild card matching routines
Someone suggested looking at GNU grep; someone else mentioned the routine
re_comp() (without observing that it's BSD-specific). But I think the
original question is about shell-style wildcard matching (aka globbing), not
RE matching. On some systems, there's a gmatch() function in libgen.a; if you
don't have that, the enclosed source ought to be useful.
Karl W. Z. Heuer (karl at ima.isc.com or uunet!ima!karl), The Walking Lint
--------cut here--------
#include "bool.h"
/*
* Wildcard matching routine by Karl Heuer. Public Domain.
*
* Test whether string s is matched by pattern p.
* Supports "?", "*", "[", each of which may be escaped with "\";
* Character classes may use "!" for negation and "-" for range.
* Not yet supported: internationalization; "\" inside brackets.
*/
bool wildmatch(char const *s, char const *p) {
register char c;
while ((c = *p++) != '\0') {
if (c == '?') {
if (*s++ == '\0') return (NO);
} else if (c == '[') {
register bool wantit = YES;
register bool seenit = NO;
if (*p == '!') {
wantit = NO;
++p;
}
c = *p++;
do {
if (c == '\0') return (NO);
if (*p == '-' && p[1] != '\0') {
if (*s >= c && *s <= p[1]) seenit = YES;
p += 2;
} else {
if (c == *s) seenit = YES;
}
} while ((c = *p++) != ']');
if (wantit != seenit) return (NO);
++s;
} else if (c == '*') {
if (*p == '\0') return (YES); /* optimize common case */
do {
if (wildmatch(s, p)) return (YES);
} while (*s++ != '\0');
return (NO);
} else if (c == '\\') {
if (*p == '\0' || *p++ != *s++) return (NO);
} else {
if (c != *s++) return (NO);
}
}
return (*s == '\0');
}
More information about the Comp.lang.c
mailing list