Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!zaphod.mps.ohio-state.edu!think.com!mintaka!spdcc!ima!dirtydog!karl From: karl@ima.isc.com (Karl Heuer) Newsgroups: comp.lang.c Subject: Re: pattern/wild card matching Summary: globbing is not regexp Message-ID: <1991Feb13.023548.16194@dirtydog.ima.isc.com> Date: 13 Feb 91 02:35:48 GMT References: <6467@saffron1.UUCP> <844@caslon.cs.arizona.edu> Sender: news@dirtydog.ima.isc.com (NEWS ADMIN) Reply-To: karl@ima.isc.com (Karl Heuer) Organization: Interactive Systems Lines: 58 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@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'); }