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 14using 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. 22bool 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. 29bool 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