Field3D
PatternMatch.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------//
2
3/*
4 * Copyright (c) 2009 Sony Pictures Imageworks Inc
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the
17 * distribution. Neither the name of Sony Pictures Imageworks nor the
18 * names of its contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33 * OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36//----------------------------------------------------------------------------//
37
42//----------------------------------------------------------------------------//
43
44// Header include
45#include "PatternMatch.h"
46
47// System includes
48#ifdef WIN32
49#include "Shlwapi.h"
50#define FNM_NOMATCH 1
51#define FNM_NOESCAPE 0
52#else
53#include <fnmatch.h>
54#endif
55
56//----------------------------------------------------------------------------//
57
59
60//----------------------------------------------------------------------------//
61// Function implementations
62//----------------------------------------------------------------------------//
63
64#ifdef WIN32
65static int
66fnmatch(const char *pattern, const char *string, int /*flags*/)
67{
68 return PathMatchSpec(string, pattern) ? 0 : FNM_NOMATCH;
69}
70#endif
71
72//----------------------------------------------------------------------------//
73
74std::vector<std::string>
75split(const std::string &s)
76{
77 return split(s, " ");
78}
79
80//----------------------------------------------------------------------------//
81
82std::vector<std::string>
83split(const std::string &s, const std::string &separatorChars)
84{
85 typedef boost::char_separator<char> CharSeparator;
86 typedef boost::tokenizer<CharSeparator> Tokenizer;
87
88 std::vector<std::string> result;
89 CharSeparator separators(separatorChars.c_str());
90 Tokenizer tokenizer(s, separators);
91
92 BOOST_FOREACH (const std::string &i, tokenizer) {
93 result.push_back(i);
94 }
95
96 return result;
97}
98
99//------------------------------------------------------------------------------
100
101bool
102match(const std::string &name, const std::string &attribute,
103 const std::vector<std::string> &patterns,
104 const MatchFlags flags)
105{
106 bool foundMatch = false;
107 bool foundExclusion = false;
108
109 if (patterns.size() == 0) {
110 return flags && MatchEmptyPattern;
111 }
112
113 BOOST_FOREACH (const std::string &i, patterns) {
114
115 if (i.size() == 0) {
116 continue;
117 }
118
119 // Check exclusion string
120 bool isExclusion = i[0] == '-' || i[0] == '^';
121 // Update string
122 const std::string pattern = isExclusion ? i.substr(1) : i;
123
124 // String to match
125 std::string s;
126
127 // Determine type of matching
128 if (pattern.find(":") != std::string::npos) {
129 // Pattern includes separator. Match against name:attribute
130 s = name + ":" + attribute;
131 } else {
132 // No separator. Just match against attribute
133 s = attribute;
134 }
135
136 // Match with wildcards
137 if (fnmatch(pattern.c_str(), s.c_str(), FNM_NOESCAPE) == 0) {
138 if (isExclusion) {
139 foundExclusion = true;
140 } else {
141 foundMatch = true;
142 }
143 }
144
145 }
146
147 return foundMatch && !foundExclusion;
148}
149
150//------------------------------------------------------------------------------
151
152bool
153match(const std::string &name, const std::string &attribute,
154 const std::string &patterns,
155 const MatchFlags flags)
156{
157 return match(name, attribute, split(patterns), flags);
158}
159
160//------------------------------------------------------------------------------
161
162bool
163match(const std::string &attribute, const std::vector<std::string> &patterns,
164 const MatchFlags flags)
165{
166 bool foundMatch = false;
167 bool foundExclusion = false;
168
169 if (patterns.size() == 0) {
170 return flags && MatchEmptyPattern;
171 }
172
173 BOOST_FOREACH (const std::string &i, patterns) {
174
175 if (i.size() == 0) {
176 continue;
177 }
178
179 // Check exclusion string
180 bool isExclusion = i[0] == '-' || i[0] == '^';
181 // Update string
182 std::string pattern = isExclusion ? i.substr(1) : i;
183
184 // Determine type of matching
185 size_t pos = pattern.find(":");
186 if (pos != std::string::npos) {
187 // Pattern includes separator. Just use second half
188 pattern = pattern.substr(pos + 1);
189 }
190
191 // Match with wildcards
192 if (fnmatch(pattern.c_str(), attribute.c_str(), FNM_NOESCAPE) == 0) {
193 if (isExclusion) {
194 foundExclusion = true;
195 } else {
196 foundMatch = true;
197 }
198 }
199
200 }
201
202 return foundMatch && !foundExclusion;
203}
204
205//------------------------------------------------------------------------------
206
207bool
208match(const std::string &attribute, const std::string &patterns,
209 const MatchFlags flags)
210{
211 return match(attribute, split(patterns), flags);
212}
213
214//------------------------------------------------------------------------------
215
216bool
217match(const FieldRes *f, const std::vector<std::string> &patterns,
218 const MatchFlags flags)
219{
220 return match(f->name, f->attribute, patterns, flags);
221}
222
223//------------------------------------------------------------------------------
224
225bool
226match(const FieldRes *f, const std::string &patterns,
227 const MatchFlags flags)
228{
229 return match(f->name, f->attribute, split(patterns), flags);
230}
231
232//----------------------------------------------------------------------------//
233
235
236//----------------------------------------------------------------------------//
bool match(const std::string &name, const std::string &attribute, const std::vector< std::string > &patterns, const MatchFlags flags)
Matches a <name>:<attribute> string against a set of patterns.
FIELD3D_NAMESPACE_OPEN std::vector< std::string > split(const std::string &s)
Splits a string into a vector of strings, using ',' as the separator.
Contains functions for pattern matching field name/attributes.
MatchFlags
@ MatchEmptyPattern
std::string attribute
Optional name of the attribute the field represents.
Definition Field.h:173
std::string name
Optional name of the field.
Definition Field.h:171
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition ns.h:60