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