/******************************************************************************* * matchespattern.cpp * Pattern-matching functions. * *------------------------------------------------------------------------------- * @version $Revision: 1.2 $ $Date: 2006/03/16 03:42:49 $ * @since 2006-01-25 * @author * David R. Tribble (david@tribble.com) * * Copyright ©2006 by David R. Tribble, all rights reserved. * Permission is granted to use, modify, and distribute this source code provided * that the original copyright and author notices remain intact and unaltered. */ // Identification static char REV[] = "@(#)tribble/cpp/lib/matchespattern.cpp $Revision: 1.2 $ $Date: 2006/03/16 03:42:49 $"; // System includes #include #include #include // Local includes #include "matchespattern.hpp" //------------------------------------------------------------------------------ // Private (non-class) functions //------------------------------------------------------------------------------ /******************************************************************************* * ::matchPat() * Compare a name to a wildcard (filename) pattern. * This is a static helper function. * * @param name * A name (filename) to compare. * * @param pat * Name pattern containing wildcards, which are: * ? - matches a single character * * - matches zero or more characters * Note that alphabetic character comparisons are case-insensitive * (e.g., "abc" matches "abc", "Abc", and "ABC"). * * @return * True if 'name' matches 'pat', otherwise false. * False is returned if either 'name' or 'pat' is null. * * @since 1.2, 2006-03-13 */ static bool matchPat(const char *name, const char *pat) { int fi = 0; int pi = 0; // Match a pathname to a filename pattern for (;;) { int fch; fch = name[fi]; switch (pat[pi++]) { case '?': // Match any single filename character if (fch == '\0' or fch == '\\' or fch == '/') return (false); fi++; break; case '*': // Match zero or more filename characters while (pat[pi] == '*') pi++; do { if (matchPat(name+fi, pat+pi)) return (true); fi++; } while (name[fi-1] != '\0'); return (false); case '\\': case '/': // Match a directory separator if (fch != '\\' and fch != '/') return (false); fi++; break; case '\0': // Match the end of the filename return (fch == '\0'); default: // Match a regular filename character if (tolower(fch) != tolower(pat[pi-1])) return (false); fi++; break; } } #if OLD_CODE // This works, but is too recursive // Compare the name to the pattern switch (pat[0]) { case '\0': // End of string return (name[0] == '\0'); case '?': // Match any single character if (name[0] == '\0') return (false); return (matchPat(name+1, pat+1)); case '*': // Match zero or more characters for (i = 0; name[i] != '\0'; i++) continue; do { if (matchPat(name+i, pat+1)) return (true); } while (i-- > 0); return (false); default: // Compare single characters, case-insensitive if (tolower(pat[0]) == tolower(name[0])) return (matchPat(name+1, pat+1)); else return (false); } #endif } //------------------------------------------------------------------------------ // Public (non-class) functions //------------------------------------------------------------------------------ /******************************************************************************* * ::matchesPattern() * Compare a name to a wildcard (filename) pattern. * * @param name * A name (filename) to compare. An empty filename ("") matches only an * empty pattern. * * @param pat * Name pattern containing wildcards, which are: * ? - matches a single character * * - matches zero or more characters * Note that alphabetic character comparisons are case-insensitive * (e.g., "abc" matches "abc", "Abc", and "ABC"). * An empty pattern ("") matches only an empty filename. * * @return * True if 'name' matches 'pat', otherwise false. * False is returned if either 'name' or 'pat' is null. * * @since 1.1, 2006-01-26 */ bool matchesPattern(const char *name, const char *pat) { // Sanity check if (name == NULL) return (false); if (pat == NULL) return (false); // Match a pathname to a filename pattern if (pat[0] == '\0' and name[0] != '\0') return (false); return (matchPat(name, pat)); } // End matchespattern.cpp