Home | History | Annotate | Line # | Download | only in common
GlobMatcher.cpp revision 1.1
      1 /*
      2  * File:	GlobMatcher.cpp
      3  *
      4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
      5  * See included license file for license details.
      6  */
      7 
      8 #include "GlobMatcher.h"
      9 
     10 #ifndef NEGATE
     11 #define NEGATE	'^'			// std cset negation char
     12 #endif
     13 
     14 using namespace elftosb;
     15 
     16 //! The glob pattern must match the \e entire test value argument in order
     17 //! for the match to be considered successful. Thus, even if, for example,
     18 //! the pattern matches all but the last character the result will be false.
     19 //!
     20 //! \retval true The test value does match the glob pattern.
     21 //! \retval false The test value does not match the glob pattern.
     22 bool GlobMatcher::match(const std::string & testValue)
     23 {
     24 	return globMatch(testValue.c_str(), m_pattern.c_str());
     25 }
     26 
     27 //! \note This glob implementation was originally written by ozan s. yigit in
     28 //!		December 1994. This is public domain source code.
     29 bool GlobMatcher::globMatch(const char *str, const char *p)
     30 {
     31 	int negate;
     32 	int match;
     33 	int c;
     34 
     35 	while (*p) {
     36 		if (!*str && *p != '*')
     37 			return false;
     38 
     39 		switch (c = *p++) {
     40 
     41 		case '*':
     42 			while (*p == '*')
     43 				p++;
     44 
     45 			if (!*p)
     46 				return true;
     47 
     48 			if (*p != '?' && *p != '[' && *p != '\\')
     49 				while (*str && *p != *str)
     50 					str++;
     51 
     52 			while (*str) {
     53 				if (globMatch(str, p))
     54 					return true;
     55 				str++;
     56 			}
     57 			return false;
     58 
     59 		case '?':
     60 			if (*str)
     61 				break;
     62 			return false;
     63 
     64 		// set specification is inclusive, that is [a-z] is a, z and
     65 		// everything in between. this means [z-a] may be interpreted
     66 		// as a set that contains z, a and nothing in between.
     67 		case '[':
     68 			if (*p != NEGATE)
     69 				negate = false;
     70 			else {
     71 				negate = true;
     72 				p++;
     73 			}
     74 
     75 			match = false;
     76 
     77 			while (!match && (c = *p++)) {
     78 				if (!*p)
     79 					return false;
     80 				if (*p == '-') {	// c-c
     81 					if (!*++p)
     82 						return false;
     83 					if (*p != ']') {
     84 						if (*str == c || *str == *p ||
     85 						    (*str > c && *str < *p))
     86 							match = true;
     87 					}
     88 					else {		// c-]
     89 						if (*str >= c)
     90 							match = true;
     91 						break;
     92 					}
     93 				}
     94 				else {			// cc or c]
     95 					if (c == *str)
     96 						match = true;
     97 					if (*p != ']') {
     98 						if (*p == *str)
     99 							match = true;
    100 					}
    101 					else
    102 						break;
    103 				}
    104 			}
    105 
    106 			if (negate == match)
    107 				return false;
    108 			// if there is a match, skip past the cset and continue on
    109 			while (*p && *p != ']')
    110 				p++;
    111 			if (!*p++)	// oops!
    112 				return false;
    113 			break;
    114 
    115 		case '\\':
    116 			if (*p)
    117 				c = *p++;
    118 		default:
    119 			if (c != *str)
    120 				return false;
    121 			break;
    122 
    123 		}
    124 		str++;
    125 	}
    126 
    127 	return !*str;
    128 }
    129 
    130