Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_smatch 4 #ifndef tools_smatch 5 #define tools_smatch 5 #define tools_smatch 6 6 7 #include "words" 7 #include "words" 8 #include <cstring> 8 #include <cstring> 9 9 10 namespace tools { 10 namespace tools { 11 11 12 inline bool match(const std::string& a_string, 12 inline bool match(const std::string& a_string,const std::string& a_pattern,bool a_check_for_wilds = true){ 13 std::string::size_type lpattern = a_pattern. 13 std::string::size_type lpattern = a_pattern.length(); 14 std::string::size_type lstring = a_string.l 14 std::string::size_type lstring = a_string.length(); 15 if ((lpattern==0)&&(lstring==0)) return true 15 if ((lpattern==0)&&(lstring==0)) return true; 16 if ((lpattern==0)&&(lstring!=0)) return true 16 if ((lpattern==0)&&(lstring!=0)) return true; 17 if ((lpattern!=0)&&(lstring==0)) return fals 17 if ((lpattern!=0)&&(lstring==0)) return false; 18 18 19 if((lpattern==1)&&(a_pattern[0]=='*')) retur 19 if((lpattern==1)&&(a_pattern[0]=='*')) return true; 20 20 21 if(a_check_for_wilds) { 21 if(a_check_for_wilds) { 22 bool some_star = false; 22 bool some_star = false; 23 for(std::string::size_type count=0;count<l 23 for(std::string::size_type count=0;count<lpattern;count++) { 24 if(a_pattern[count]=='*') {some_star = t 24 if(a_pattern[count]=='*') {some_star = true;break;} 25 } 25 } 26 if(!some_star) { // no wildcard : 26 if(!some_star) { // no wildcard : 27 return (a_pattern==a_string ? true : fal 27 return (a_pattern==a_string ? true : false ); 28 } 28 } 29 } 29 } 30 30 31 // complex pattern : 31 // complex pattern : 32 //std::string::size_type* wps = new std::str 32 //std::string::size_type* wps = new std::string::size_type[2*lpattern]; 33 if((2*lpattern)>1024) return false; //throw 33 if((2*lpattern)>1024) return false; //throw 34 std::string::size_type wps[1024]; //OPTIMIZA 34 std::string::size_type wps[1024]; //OPTIMIZATION : we gain a lot with that. 35 35 36 unsigned int wn; 36 unsigned int wn; 37 std::string::size_type* wls = wps+lpattern; 37 std::string::size_type* wls = wps+lpattern; 38 words(a_pattern,"*",false,wn,wps,wls); 38 words(a_pattern,"*",false,wn,wps,wls); 39 if(!wn) { 39 if(!wn) { 40 //delete [] wps; 40 //delete [] wps; 41 return true; // only wildcards : 41 return true; // only wildcards : 42 } 42 } 43 43 44 // tricky case : 44 // tricky case : 45 char* token = (char*)a_string.c_str(); 45 char* token = (char*)a_string.c_str(); 46 {for(unsigned int count=0;count<wn;count++) { 46 {for(unsigned int count=0;count<wn;count++) { 47 size_t lword = wls[count]; 47 size_t lword = wls[count]; 48 if(!lword) continue;//should never happen 48 if(!lword) continue;//should never happen ! 49 //WARNING : ws_pos does not have a null ch 49 //WARNING : ws_pos does not have a null char at ws_pos+lword ! 50 char* ws_pos = (char*)(a_pattern.c_str()+w 50 char* ws_pos = (char*)(a_pattern.c_str()+wps[count]); 51 if(count==0) { 51 if(count==0) { 52 if(a_pattern[0]!='*') { 52 if(a_pattern[0]!='*') { 53 // Begin of pattern (ws[0]) and a_stri 53 // Begin of pattern (ws[0]) and a_string must match : 54 if(::strncmp(token,ws_pos,lword)) { 54 if(::strncmp(token,ws_pos,lword)) { 55 //delete [] wps; 55 //delete [] wps; 56 return false; 56 return false; 57 } 57 } 58 token = token + lword; 58 token = token + lword; 59 continue; 59 continue; 60 } 60 } 61 } 61 } 62 char old_char = *(ws_pos+lword); 62 char old_char = *(ws_pos+lword); 63 *(ws_pos+lword) = 0; 63 *(ws_pos+lword) = 0; 64 char* pos = ::strstr(token,ws_pos); 64 char* pos = ::strstr(token,ws_pos); 65 *(ws_pos+lword) = old_char; 65 *(ws_pos+lword) = old_char; 66 if(!pos) { 66 if(!pos) { 67 //delete [] wps; 67 //delete [] wps; 68 return false; 68 return false; 69 } 69 } 70 if((count==(wn-1)) && (a_pattern[lpattern- 70 if((count==(wn-1)) && (a_pattern[lpattern-1]!='*') ) { // Last word. 71 // Compare last word and end of a_string 71 // Compare last word and end of a_string. 72 if(::strncmp(a_string.c_str()+lstring-lw 72 if(::strncmp(a_string.c_str()+lstring-lword,ws_pos,lword)) { 73 //delete [] wps; 73 //delete [] wps; 74 return false; 74 return false; 75 } 75 } 76 break; 76 break; 77 } else { 77 } else { 78 token = pos + lword; 78 token = pos + lword; 79 } 79 } 80 }} 80 }} 81 81 82 //delete [] wps; 82 //delete [] wps; 83 return true; 83 return true; 84 } 84 } 85 85 86 //for tools/app/find.cpp : 86 //for tools/app/find.cpp : 87 inline bool match2(const std::string& a_string 87 inline bool match2(const std::string& a_string,const std::string& a_pattern){ 88 return match(a_string,a_pattern,true); 88 return match(a_string,a_pattern,true); 89 } 89 } 90 90 91 inline void filter(std::vector<std::string>& a 91 inline void filter(std::vector<std::string>& a_v, 92 const std::string& a_patter 92 const std::string& a_pattern, 93 bool a_check_for_wilds = tr 93 bool a_check_for_wilds = true){ 94 std::vector<std::string>::iterator it; 94 std::vector<std::string>::iterator it; 95 for(it=a_v.begin();it!=a_v.end();) { 95 for(it=a_v.begin();it!=a_v.end();) { 96 if(match(*it,a_pattern,a_check_for_wilds)) 96 if(match(*it,a_pattern,a_check_for_wilds)) { 97 it++; 97 it++; 98 } else { 98 } else { 99 it = a_v.erase(it); 99 it = a_v.erase(it); 100 } 100 } 101 } 101 } 102 } 102 } 103 103 104 } 104 } 105 105 106 #endif 106 #endif