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