- Timestamp:
- Jun 13, 2010, 6:46:29 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/Configuration.cc
r1097 r1098 366 366 std::string res; 367 367 std::vector<std::string> vec; 368 if (!regexp( str.begin(), str.end(), dic.first.begin(),dic.first.end(),vec)){368 if (!regexp(dic.first, str, vec)) { 369 369 std::stringstream mess; 370 370 mess << "invalid config file: " -
trunk/lib/utility.cc
r1097 r1098 158 158 bool fnmatch(const std::string& pattern, const std::string& str) 159 159 { 160 int res = ::fnmatch(pattern.c_str(), str.c_str(), FNM_PERIOD);160 int res = ::fnmatch(pattern.c_str(), str.c_str(), 0); 161 161 if (res==0) 162 162 return true; … … 223 223 224 224 225 bool regexp(std::string::const_iterator first1, 226 std::string::const_iterator last1, 227 std::string::const_iterator first2, 228 std::string::const_iterator last2, 225 bool regexp(const std::string& pattern, const std::string& str, 229 226 std::vector<std::string>& vec) 230 227 { 231 if (vec.empty()) 232 vec.push_back(""); 233 234 // first two cases when ranges are empty 235 if (first1==last1 && first2==last2){ 236 vec.pop_back(); 237 return true; 238 } 228 bool regexp__(std::string::const_iterator first1, 229 std::string::const_iterator last1, 230 std::string::const_iterator first2, 231 std::string::const_iterator last2, 232 std::vector<std::string>::iterator item); 233 234 // find number of special chars 235 size_t count=0; 236 for (std::string::const_iterator i=pattern.begin(); i!=pattern.end(); ++i) 237 if (*i=='*' || *i=='?' || *i=='[') 238 ++count; 239 vec.resize(count); 240 return regexp__(pattern.begin(), pattern.end(), str.begin(), str.end(), 241 vec.begin()); 242 } 243 244 bool regexp__(std::string::const_iterator first1, 245 std::string::const_iterator last1, 246 std::string::const_iterator first2, 247 std::string::const_iterator last2, 248 std::vector<std::string>::iterator item) 249 { 250 if (first1==last1) { 251 return first2==last2; 252 } 253 if (*first1 == '*') { 254 if (first2<last2) { 255 item->push_back(*first2); 256 if (regexp__(first1, last1, first2+1, last2, item)) 257 return true; 258 item->resize(item->size()-1); 259 } 260 return regexp__(first1+1, last1, first2, last2, item+1); 261 } 262 if (*first1 == '?') { 263 if (first2==last2) 264 return false; 265 *item = *first2; 266 return regexp__(first1+1, last1, first2+1, last2, item+1); 267 } 268 if (*first1 == '[') { 269 if (first2==last2) 270 return false; 271 bool found = false; 272 while (*first1 != ']') { 273 if (*first1 == *first2) { 274 found = true; 275 *item = *first2; 276 } 277 ++first1; 278 assert(first1!=last1); 279 } 280 return regexp__(first1+1, last1, first2+1, last2, item+1); 281 /* 282 while (*first2 != ']') { 283 if (*first2==*first1) { 284 found = true; 285 vec.back() = *first1; 286 vec.push_back(""); 287 } 288 ++first2; 289 assert(first2!=last2); 290 } 291 if (!found) 292 return false; 293 return regexp(first1+1, last1, first2+1, last2, vec); 294 */ 295 } 296 297 if (first2==last2) 298 return false; 299 if (*first1 != *first2) 300 return false; 301 return regexp__(first1+1, last1, first2+1, last2, item); 302 303 /* 304 305 306 307 if (first1==last1) 308 return false; 309 if (*first1 != *first2) 310 return false; 311 return regexp(first1+1, last1, first2+1, last2, vec); 312 313 /// hm 239 314 if (first1==last1 || first2==last2) 240 315 return false; … … 274 349 return false; 275 350 return regexp(++first1, last1, ++first2, last2, vec); 351 */ 276 352 } 277 353 -
trunk/lib/utility.h
r1090 r1098 165 165 166 166 /** 167 \return true if first range match second range168 169 Second range may contain wildcards (such as '*' and '?'),in170 which case vector \a vec is filled with the corresponding strings171 in first range. The algorithm is greedy, i.e., wildcard * iswill167 \return true if \a str matches \a pattern 168 169 \a pattern may contain wildcards '*', '?' and \a vec will contain 170 the matching string in \a str. If it's not a match, \a vec is 171 undefined. The algorithm is greedy, i.e., wildcards '*' will 172 172 consume as many charcters as possible. 173 173 174 174 \note \a vec is supposed to be empty 175 175 */ 176 bool regexp(std::string::const_iterator first1, 177 std::string::const_iterator end1, 178 std::string::const_iterator first2, 179 std::string::const_iterator end2, 176 bool regexp(const std::string& pattern, const std::string& str, 180 177 std::vector<std::string>& vec); 181 178 -
trunk/test/utility_test.cc
r1096 r1098 43 43 ok &= test_fnmatch(true,"peter", "peter"); 44 44 ok &= test_fnmatch(false,"peter", "peterj"); 45 46 ok &= test_fnmatch(true,"*", "peterj"); 45 47 ok &= test_fnmatch(true,"p*", "peterj"); 46 48 ok &= test_fnmatch(true, "p*", "peter"); 47 49 ok &= test_fnmatch(false, "p*j", "peter"); 50 ok &= test_fnmatch(true, "p*j", "peterj"); 48 51 ok &= test_fnmatch(true, "*peter", "peter"); 52 53 ok &= test_fnmatch(true, "p?ter", "peter"); 54 ok &= test_fnmatch(false, "p?er", "peter"); 55 ok &= test_fnmatch(false, "p?eter", "peter"); 49 56 50 57 ok &= test_fnmatch(true, "filename", "filename"); 51 58 ok &= test_fnmatch(true, "*name", "filename"); 52 59 ok &= test_fnmatch(true, "[fa]il?name", "filename"); 60 ok &= test_fnmatch(true, "[fa]*il?name", "ffilename"); 61 62 ok &= test_fnmatch(true, "[fa]*il?name", "fafafailename"); 63 ok &= test_fnmatch(false, "[fa]?il?name", "ilename"); 64 ok &= test_fnmatch(false, "?[fa]il?name", "ilename"); 65 ok &= test_fnmatch(true, "[fa]il?name", "filename"); 66 ok &= test_fnmatch(false, "[fa]?il?name", "fafafailename"); 67 53 68 ok &= test_fnmatch(true, "*name", "/path/to/filename"); 54 69 ok &= test_fnmatch(true, "*name", "file.name"); 55 // posix dictates that leading persion can not be matched by wildcard 56 ok &= test_fnmatch(false, "*.txt", ".file.txt"); 70 // posix dictates that leading period can not be matched by 71 // wildcard, but here we allow match 72 ok &= test_fnmatch(true, "*.txt", ".file.txt"); 73 57 74 58 75 std::vector<std::string> vec; 59 76 ok &= test_regexp(true,"abcde", "abcde", vec); 77 vec.push_back("c"); 78 ok &= test_regexp(true,"ab?de", "abcde", vec); 79 vec[0] = "bcd"; 80 ok &= test_regexp(true,"a*e", "abcde", vec); 60 81 vec.push_back(""); 61 ok &= test_regexp(true,"abcde", "abcd?e", vec); 62 vec[0]="c"; 63 ok &= test_regexp(true,"abcde", "ab?de", vec); 64 vec[0] = "bcd"; 65 ok &= test_regexp(true,"abcde", "a*e", vec); 66 vec.push_back(""); 67 ok &= test_regexp(true,"abcddf", "a*d*f", vec); 82 ok &= test_regexp(true,"a*d*f", "abcddf", vec); 68 83 vec[0] = "bc"; 69 84 vec[1] = "ef"; 70 ok &= test_regexp(true,"a bcdefg", "a*d*g", vec);85 ok &= test_regexp(true,"a*d*g", "abcdefg", vec); 71 86 vec.push_back(""); 72 ok &= test_regexp(true,"abcdefg", "a*d*?g", vec);73 87 vec[1]="e"; 74 88 vec[2]="f"; 75 ok &= test_regexp(true,"abcdefg", "a*d??g", vec); 89 ok &= test_regexp(true,"a*d*?g", "abcdefg", vec); 90 ok &= test_regexp(true,"a*d??g", "abcdefg", vec); 91 vec.resize(2); 92 vec[0]="f"; 93 vec[1]="e"; 94 ok &= test_regexp(true, "[fa]il?name", "filename", vec); 76 95 77 96 if (ok) … … 84 103 using namespace theplu::svndigest; 85 104 bool res = fnmatch(a.c_str(), b.c_str()); 86 if (res == answ) 105 // check that fnmatch and regexp agree 106 std::vector<std::string> v; 107 bool res2 = regexp(a, b, v); 108 if (res == answ && res2==answ) 87 109 return true; 88 std::cerr << "fnmatch(" << a << ", " << b << ") results " 89 << res 90 << ". Expects " << answ << std::endl; 110 if (res!=answ) 111 std::cerr << "fnmatch(" << a << ", " << b << ") results " 112 << res 113 << ". Expects " << answ << std::endl; 114 if (res2!=answ) 115 std::cerr << "regexp(" << b << ", " << a << ") results " 116 << res2 117 << ". Expects " << answ << std::endl; 91 118 return false; 92 119 } … … 107 134 using namespace theplu::svndigest; 108 135 std::vector<std::string> v; 109 bool res = regexp(a .begin(), a.end(), b.begin(), b.end(), v);136 bool res = regexp(a, b, v); 110 137 if (res!=ans || v!=vec) { 111 138 std::cerr << "regexp(" << a << ", " << b << ") results "
Note: See TracChangeset
for help on using the changeset viewer.