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