107 lines
2.9 KiB
Plaintext
107 lines
2.9 KiB
Plaintext
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
|
// See the file tools.license for terms.
|
|
|
|
#ifndef tools_smatch
|
|
#define tools_smatch
|
|
|
|
#include "words"
|
|
#include <cstring>
|
|
|
|
namespace tools {
|
|
|
|
inline bool match(const std::string& a_string,const std::string& a_pattern,bool a_check_for_wilds = true){
|
|
std::string::size_type lpattern = a_pattern.length();
|
|
std::string::size_type lstring = a_string.length();
|
|
if ((lpattern==0)&&(lstring==0)) return true;
|
|
if ((lpattern==0)&&(lstring!=0)) return true;
|
|
if ((lpattern!=0)&&(lstring==0)) return false;
|
|
|
|
if((lpattern==1)&&(a_pattern[0]=='*')) return true;
|
|
|
|
if(a_check_for_wilds) {
|
|
bool some_star = false;
|
|
for(std::string::size_type count=0;count<lpattern;count++) {
|
|
if(a_pattern[count]=='*') {some_star = true;break;}
|
|
}
|
|
if(!some_star) { // no wildcard :
|
|
return (a_pattern==a_string ? true : false );
|
|
}
|
|
}
|
|
|
|
// complex pattern :
|
|
//std::string::size_type* wps = new std::string::size_type[2*lpattern];
|
|
if((2*lpattern)>1024) return false; //throw
|
|
std::string::size_type wps[1024]; //OPTIMIZATION : we gain a lot with that.
|
|
|
|
unsigned int wn;
|
|
std::string::size_type* wls = wps+lpattern;
|
|
words(a_pattern,"*",false,wn,wps,wls);
|
|
if(!wn) {
|
|
//delete [] wps;
|
|
return true; // only wildcards :
|
|
}
|
|
|
|
// tricky case :
|
|
char* token = (char*)a_string.c_str();
|
|
{for(unsigned int count=0;count<wn;count++) {
|
|
size_t lword = wls[count];
|
|
if(!lword) continue;//should never happen !
|
|
//WARNING : ws_pos does not have a null char at ws_pos+lword !
|
|
char* ws_pos = (char*)(a_pattern.c_str()+wps[count]);
|
|
if(count==0) {
|
|
if(a_pattern[0]!='*') {
|
|
// Begin of pattern (ws[0]) and a_string must match :
|
|
if(::strncmp(token,ws_pos,lword)) {
|
|
//delete [] wps;
|
|
return false;
|
|
}
|
|
token = token + lword;
|
|
continue;
|
|
}
|
|
}
|
|
char old_char = *(ws_pos+lword);
|
|
*(ws_pos+lword) = 0;
|
|
char* pos = ::strstr(token,ws_pos);
|
|
*(ws_pos+lword) = old_char;
|
|
if(!pos) {
|
|
//delete [] wps;
|
|
return false;
|
|
}
|
|
if((count==(wn-1)) && (a_pattern[lpattern-1]!='*') ) { // Last word.
|
|
// Compare last word and end of a_string.
|
|
if(::strncmp(a_string.c_str()+lstring-lword,ws_pos,lword)) {
|
|
//delete [] wps;
|
|
return false;
|
|
}
|
|
break;
|
|
} else {
|
|
token = pos + lword;
|
|
}
|
|
}}
|
|
|
|
//delete [] wps;
|
|
return true;
|
|
}
|
|
|
|
//for tools/app/find.cpp :
|
|
inline bool match2(const std::string& a_string,const std::string& a_pattern){
|
|
return match(a_string,a_pattern,true);
|
|
}
|
|
|
|
inline void filter(std::vector<std::string>& a_v,
|
|
const std::string& a_pattern,
|
|
bool a_check_for_wilds = true){
|
|
std::vector<std::string>::iterator it;
|
|
for(it=a_v.begin();it!=a_v.end();) {
|
|
if(match(*it,a_pattern,a_check_for_wilds)) {
|
|
it++;
|
|
} else {
|
|
it = a_v.erase(it);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|