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 #include <fnmatch.h>
49 
50 //----------------------------------------------------------------------------//
51 
53 
54 //----------------------------------------------------------------------------//
55 // Function implementations
56 //----------------------------------------------------------------------------//
57 
58 std::vector<std::string>
59 split(const std::string &s)
60 {
61  return split(s, " ");
62 }
63 
64 //----------------------------------------------------------------------------//
65 
66 std::vector<std::string>
67 split(const std::string &s, const std::string &separatorChars)
68 {
69  typedef boost::char_separator<char> CharSeparator;
70  typedef boost::tokenizer<CharSeparator> Tokenizer;
71 
72  std::vector<std::string> result;
73  CharSeparator separators(separatorChars.c_str());
74  Tokenizer tokenizer(s, separators);
75 
76  BOOST_FOREACH (const std::string &i, tokenizer) {
77  result.push_back(i);
78  }
79 
80  return result;
81 }
82 
83 //------------------------------------------------------------------------------
84 
85 bool
86 match(const std::string &name, const std::string &attribute,
87  const std::vector<std::string> &patterns,
88  const MatchFlags flags)
89 {
90  bool foundMatch = false;
91  bool foundExclusion = false;
92 
93  if (patterns.size() == 0) {
94  return flags && MatchEmptyPattern;
95  }
96 
97  BOOST_FOREACH (const std::string &i, patterns) {
98 
99  if (i.size() == 0) {
100  continue;
101  }
102 
103  // Check exclusion string
104  bool isExclusion = i[0] == '-' || i[0] == '^';
105  // Update string
106  const std::string pattern = isExclusion ? i.substr(1) : i;
107 
108  // String to match
109  std::string s;
110 
111  // Determine type of matching
112  if (pattern.find(":") != std::string::npos) {
113  // Pattern includes separator. Match against name:attribute
114  s = name + ":" + attribute;
115  } else {
116  // No separator. Just match against attribute
117  s = attribute;
118  }
119 
120  // Match with wildcards
121  if (fnmatch(pattern.c_str(), s.c_str(), FNM_NOESCAPE) == 0) {
122  if (isExclusion) {
123  foundExclusion = true;
124  } else {
125  foundMatch = true;
126  }
127  }
128 
129  }
130 
131  return foundMatch && !foundExclusion;
132 }
133 
134 //------------------------------------------------------------------------------
135 
136 bool
137 match(const std::string &name, const std::string &attribute,
138  const std::string &patterns,
139  const MatchFlags flags)
140 {
141  return match(name, attribute, split(patterns), flags);
142 }
143 
144 //------------------------------------------------------------------------------
145 
146 bool
147 match(const std::string &attribute, const std::vector<std::string> &patterns,
148  const MatchFlags flags)
149 {
150  bool foundMatch = false;
151  bool foundExclusion = false;
152 
153  if (patterns.size() == 0) {
154  return flags && MatchEmptyPattern;
155  }
156 
157  BOOST_FOREACH (const std::string &i, patterns) {
158 
159  if (i.size() == 0) {
160  continue;
161  }
162 
163  // Check exclusion string
164  bool isExclusion = i[0] == '-' || i[0] == '^';
165  // Update string
166  std::string pattern = isExclusion ? i.substr(1) : i;
167 
168  // Determine type of matching
169  size_t pos = pattern.find(":");
170  if (pos != std::string::npos) {
171  // Pattern includes separator. Just use second half
172  pattern = pattern.substr(pos + 1);
173  }
174 
175  // Match with wildcards
176  if (fnmatch(pattern.c_str(), attribute.c_str(), FNM_NOESCAPE) == 0) {
177  if (isExclusion) {
178  foundExclusion = true;
179  } else {
180  foundMatch = true;
181  }
182  }
183 
184  }
185 
186  return foundMatch && !foundExclusion;
187 }
188 
189 //------------------------------------------------------------------------------
190 
191 bool
192 match(const std::string &attribute, const std::string &patterns,
193  const MatchFlags flags)
194 {
195  return match(attribute, split(patterns), flags);
196 }
197 
198 //------------------------------------------------------------------------------
199 
200 bool
201 match(const FieldRes *f, const std::vector<std::string> &patterns,
202  const MatchFlags flags)
203 {
204  return match(f->name, f->attribute, patterns, flags);
205 }
206 
207 //------------------------------------------------------------------------------
208 
209 bool
210 match(const FieldRes *f, const std::string &patterns,
211  const MatchFlags flags)
212 {
213  return match(f->name, f->attribute, split(patterns), flags);
214 }
215 
216 //----------------------------------------------------------------------------//
217 
219 
220 //----------------------------------------------------------------------------//
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition: ns.h:60
Contains functions for pattern matching field name/attributes.
std::string attribute
Optional name of the attribute the field represents.
Definition: Field.h:178
MatchFlags
Definition: PatternMatch.h:64
bool match(const std::string &name, const std::string &attribute, const std::vector< std::string > &patterns, const MatchFlags flags)
Matches a : 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.
std::string name
Optional name of the field.
Definition: Field.h:176