inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/smanip
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_smanip
00005 #define inlib_smanip
00006 
00007 #include "sep"
00008 
00009 #include <vector>
00010 #include <cstring>
00011 
00012 #include "sout"   //for back compatibility.
00013 #include "words"  //for back compatibility.
00014 #include "sto"    //for back compatibility.
00015 #include "strip"  //for back compatibility.
00016 #include "path"   //for back compatibility.
00017 #include "sjust"  //for back compatibility.
00018 #include "srep"  //for back compatibility.
00019 
00020 namespace inlib {
00021 
00022 inline bool belong(const std::vector<std::string>& a_vec,
00023                    const std::string& a_s) {
00024   std::vector<std::string>::const_iterator it;
00025   for(it=a_vec.begin();it!=a_vec.end();++it) {
00026     if(*it==a_s) return true;
00027   }
00028   return false;
00029 }
00030 
00031 inline bool match(const std::string& a_string,const std::string& a_pattern){
00032   std::string::size_type lpattern = a_pattern.length();
00033   std::string::size_type lstring  = a_string.length();
00034   if ((lpattern==0)&&(lstring==0)) return true;
00035   if ((lpattern==0)&&(lstring!=0)) return true;
00036   if ((lpattern!=0)&&(lstring==0)) return false;
00037 
00038   if(a_pattern=="*") return true; // pattern is * :
00039 
00040  {bool some_star = false;
00041   for(unsigned int count=0;count<lpattern;count++) {
00042     if(a_pattern[count]=='*') {some_star = true;break;}
00043   }
00044   if(!some_star) {  // no wildcard :
00045     return (a_pattern==a_string ? true : false );
00046   }}
00047 
00048   // complex pattern :
00049   std::vector<std::string> ws;
00050   words(a_pattern,"*",false,ws);  
00051   if(ws.empty()) return true; // only wildcards :
00052 
00053   // tricky case :
00054   unsigned int wnumber = ws.size();
00055   char* token = (char*)a_string.c_str();
00056  {for(unsigned int count=0;count<wnumber;count++) { 
00057     unsigned int lword = ws[count].size(); 
00058     if(!lword) continue;//should never happen !
00059     if(count==0) {
00060       if(a_pattern[0]!='*') {
00061         // Begin of pattern (ws[0]) and a_string must match :
00062         if(::strncmp(token,ws[count].c_str(),lword)) return false;
00063         token = token + lword;
00064         continue;
00065       }
00066     }
00067     char* pos = ::strstr(token,ws[count].c_str());
00068     if(!pos) return false;
00069     if((count==(wnumber-1)) && (a_pattern[lpattern-1]!='*') ) { // Last word.
00070       // Compare last word and end of a_string.
00071       if(::strcmp(a_string.c_str()+lstring-lword,ws[count].c_str())) 
00072         return false;
00073       break;
00074     } else {
00075       token = pos + lword;
00076     }
00077   }}
00078   return true;
00079 }
00080 
00081 inline unsigned int numchar(const std::string& a_string,char a_c){
00082   unsigned int num = 0;  
00083   std::string::const_iterator it;
00084   for(it=a_string.begin();it!=a_string.end();++it) {
00085     if((*it)==a_c) num++;
00086   }
00087   return num;
00088 }
00089 
00090 inline void replace(std::string& a_string,char a_old,char a_new){
00091   for(std::string::iterator it=a_string.begin();it!=a_string.end();++it) {
00092     if((*it)==a_old) *it = a_new;
00093   }
00094 }
00095 
00096 inline std::vector<std::string> path_words(const std::string& a_path,bool& a_absolute,bool& a_win_path,std::string& a_drive){
00097 
00098   //  a_path could be at the Windows syntax : <drive>:\dir1\dir2...
00099   // If so, only dir1, dirn are put in a_words.
00100 
00101   std::string path = a_path;
00102   std::string::size_type pos = path.find('\\');
00103   a_win_path = (pos==std::string::npos?false:true);
00104   if(a_win_path) {
00105     replace(path,"\\","/");
00106     pos = path.find(':');
00107     if(pos!=std::string::npos) { //drive 
00108       a_drive = path.substr(0,pos);
00109       path = path.substr(pos+1,path.size()-(pos+1));
00110     } else {
00111       a_drive = "";
00112     }
00113   } else {
00114     a_drive = "";
00115   }
00116 
00117   a_absolute = (path.size()&&(path[0]=='/')?true:false);
00118 
00119   return words(path,"/");
00120 }
00121 
00122 inline bool remove(std::vector<std::string>& a_strings,const std::string& a_string){
00123   bool found_some = false;
00124   //std::vector<std::string>::iterator it;
00125   //for(it=a_strings.begin();it!=a_strings.end();) {
00126   //  if(*it==a_string) {
00127   //    it = a_strings.erase(it);
00128   //    found_some = true;
00129   //  } else {
00130   //    ++it;
00131   //  }
00132   //}
00133   //brut force avoiding erase(). For Android + inlib/stl.
00134   std::vector<std::string> ss;
00135   std::vector<std::string>::iterator it;
00136   for(it=a_strings.begin();it!=a_strings.end();++it) {
00137     if(*it==a_string) {
00138       found_some = true;
00139     } else {
00140       ss.push_back(*it);
00141     }
00142   }
00143   a_strings = ss;
00144   return found_some;
00145 }
00146 
00147 inline void tolowercase(std::string& a_string){
00148   for(std::string::iterator it=a_string.begin();it!=a_string.end();++it) {
00149     char c = *it;
00150     *it = ((c) >= 'A' && (c) <= 'Z' ?  c - 'A' + 'a' : c);
00151   }
00152 }
00153 
00154 inline void touppercase(std::string& a_string){
00155   for(std::string::iterator it=a_string.begin();it!=a_string.end();++it) {
00156     char c = *it;
00157     *it = ((c) >= 'a' && (c) <= 'z' ?  c - 'a' + 'A' : c);
00158   }
00159 }
00160 
00161 inline bool is_ip(const std::string& a_string){
00162   if(a_string.empty()) return false;
00163   if(a_string[0]=='.') return false;
00164   if(a_string[a_string.size()-1]=='.') return false;
00165   unsigned int ndot = 0;  
00166   std::string::const_iterator it;
00167   for(it=a_string.begin();it!=a_string.end();++it) {
00168     if((*it)=='.') {
00169       ndot++;
00170     } else if( ((*it)=='0') || ((*it)=='1') ||
00171                ((*it)=='2') || ((*it)=='3') ||
00172                ((*it)=='4') || ((*it)=='5') ||
00173                ((*it)=='6') || ((*it)=='7') ||
00174                ((*it)=='8') || ((*it)=='9') ){
00175     } else {
00176       return false;
00177     }
00178   }
00179   if(ndot!=3) return false;
00180   return true;
00181 }
00182 
00183 //used in OpenPAW, BatchLab.
00184 inline bool is_f77(const std::string& a_path){
00185   std::string sfx = suffix(a_path);
00186   tolowercase(sfx);
00187   if(sfx=="f") return true;       //the standard.
00188   if(sfx=="for") return true;     //for opaw. Known by g77.
00189   if(sfx=="ftn") return true;     //for opaw.
00190   if(sfx=="fortran") return true; //for opaw.
00191   if(sfx=="f77") return true;
00192   return false;
00193 }
00194 
00195 //used in OpenPAW, BatchLab.
00196 inline bool is_cpp(const std::string& a_path){
00197   std::string sfx = suffix(a_path);
00198   tolowercase(sfx);
00199   if(sfx=="c") return true;
00200   if(sfx=="cxx") return true;
00201   if(sfx=="cpp") return true;
00202   if(sfx=="C") return true;
00203   return false;
00204 }
00205 
00206 inline std::string to_xml(const std::string& a_string){
00207   // > : &lt;
00208   // < : &gt;
00209   // & : &amp;
00210   // " : &quot;
00211   // ' : &apos;
00212   std::string s = a_string;
00213   replace(s,"<","&lt;");
00214   replace(s,">","&gt;");
00215   replace(s,"&","&amp;");
00216   replace(s,"\"","&quot;");
00217   replace(s,"'","&apos;");
00218   return s;
00219 }
00220 
00221 inline std::string to_string(const std::vector<std::string>& a_strings,const std::string& a_sep,bool a_sep_at_end = false){
00222   unsigned int number = a_strings.size();
00223   if(number<=0) return "";
00224   std::string result;
00225   number--;
00226   for(unsigned int index=0;index<number;index++) {
00227     result += a_strings[index];
00228     result += a_sep;
00229   }
00230   result += a_strings[number];
00231   if(a_sep_at_end) result += a_sep;
00232   return result;
00233 }
00234 
00235 inline std::string to_string(unsigned int a_linen,const char* a_lines[]) {
00236   std::string s;
00237   for(unsigned int index=0;index<a_linen;index++) {
00238     s += std::string(a_lines[index]);
00239     s += "\n";
00240   }
00241   return s;
00242 }
00243 
00244 inline std::vector<std::string> to(int a_argc,char** a_argv) {
00245   std::vector<std::string> v;
00246   for(int index=0;index<a_argc;index++) v.push_back(a_argv[index]);
00247   return v;
00248 }
00249 
00250 // same logic as words() function.
00251 template <class T>
00252 inline bool values(const std::string& a_string,const std::string& a_sep,bool a_take_empty,std::vector<T>& a_values){
00253   a_values.clear();
00254   if(a_string.empty()) return true;
00255   std::string::size_type lim = (a_take_empty?0:1);
00256   if(a_sep.empty()) {
00257     T value;
00258     if(!to<T>(a_string,value)) {
00259       a_values.clear();
00260       return false;
00261     }
00262     a_values.push_back(value);
00263   } else {
00264     std::string::size_type l = a_string.length();
00265     std::string::size_type llimiter = a_sep.length();
00266     std::string::size_type pos = 0;
00267     while(true) {
00268       std::string::size_type index = a_string.find(a_sep,pos);
00269       if(index==std::string::npos){ // Last word.
00270         if((l-pos)>=lim) {
00271           T value;
00272           if(!to<T>(a_string.substr(pos,l-pos),value)) {
00273             a_values.clear();
00274             return false;
00275           }
00276           a_values.push_back(value);
00277         }
00278         break;
00279       } else {
00280         //     abcxxxef
00281         //     0  3  67
00282         if((index-pos)>=lim) {
00283           T value;
00284           if(!to<T>(a_string.substr(pos,index-pos),value)) {
00285             a_values.clear();
00286             return false;
00287           }
00288           a_values.push_back(value);
00289         }
00290         pos = index + llimiter;
00291       }
00292     }
00293   }
00294   return true;
00295 }
00296 
00297 }
00298 
00299 #include <cstdlib> //::strtol
00300 
00301 namespace inlib {
00302 
00303 inline bool version(const std::string& a_string,std::vector<unsigned int>& a_version) {
00304   // a_string is of the form [v,V][<number><char>]<number>
00305   // Examples : 0 1.2 v0 v1r2 V1r2p3 v0.1.3
00306   unsigned int number = a_string.size();
00307   if(!number) {
00308     a_version.clear();
00309     return false;
00310   }
00311   char* pos = (char*)a_string.c_str();
00312   if( ((*pos)=='v') || ((*pos)=='V') ) {
00313     if(number==1) {
00314       a_version.clear();
00315       return false; //a_string is only 'v' or 'V' !
00316     }
00317     pos++;
00318   }
00319   while(*pos!='\0') {
00320     char* s;
00321     long v = ::strtol(pos,&s,10);
00322     if(s==pos) {
00323       a_version.clear();
00324       return false;
00325     }
00326     if(v<0) {
00327       a_version.clear();
00328       return false;
00329     }
00330     a_version.push_back((unsigned int)v);
00331     pos = s; //Could be at end.
00332     if(*pos=='\0') break;
00333     // Next char is then not a digit. Skip it.
00334     pos++;
00335   }
00336   return true;
00337 }
00338 
00339 
00340 inline bool is_version(const std::string& a_string) {
00341   std::vector<unsigned int> vers;
00342   return version(a_string,vers);
00343 }
00344 
00345 inline std::string remove_version(const std::string& a_string) {
00346   // replace "@@top@@/pack/vers" -> "@@top@@/pack".
00347   std::string sold = a_string;
00348   replace(sold,"\"",sep()+"@quote@"); //To treat AIDA/v3r2p1"/src
00349   std::vector<std::string> words = inlib::words(sold,sep());
00350   unsigned int wordn = words.size();
00351   std::string snew;
00352   for(unsigned int index=0;index<wordn;index++) {
00353     std::vector<unsigned int> vers;
00354     std::string word = words[index];
00355     if(!version(word,vers)) {
00356       if(snew.size()) snew += sep();
00357       snew += words[index];
00358     }
00359   }
00360   replace(snew,sep()+"@quote@","\"");
00361   return snew;
00362 }
00363 
00364 inline bool polynomial_degree(const std::string& a_string,int& a_degree){
00365   // a_string = [p,P,Polynomial]<integer degree>
00366   // We extract <degree> from the upper.
00367   // The degree is the maximum "x" power.
00368   // For example P1 is ax+b which of degree 1.
00369   // For example P2 is ax*x+bx+c which of degree 2.
00370   std::string s = a_string;
00371   tolowercase(s);
00372   replace(s,"polynomial","p");
00373   a_degree = 0;
00374   if(s.size()<=0) return false;
00375   if(s[0]!='p') return false;
00376   int number = 0;
00377   if(!to<int>(s.substr(1,s.size()-1),number)) return false;
00378   a_degree = number;
00379   return true;
00380 }
00381 
00382 }
00383 
00384 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines