Files
geant4/source/analysis/g4tools/include/tools/smatch
T
2020-12-04 12:30:43 +01:00

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 inlib/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