Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/args is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_args
0005 #define tools_args
0006 
0007 #ifdef TOOLS_MEM
0008 #include "mem"
0009 #include "S_STRING"
0010 #endif
0011 
0012 #include "sout"
0013 #include "strip"
0014 #include "words"
0015 #include "sto"
0016 #include "forit"
0017 #include "mnmx"
0018 //#include "squote"
0019 
0020 #include <ostream>
0021 
0022 namespace tools {
0023 
0024 class args {
0025 #ifdef TOOLS_MEM
0026 public:
0027   TOOLS_SCLASS(tools::args)
0028 #endif
0029 public:
0030   typedef std::pair<std::string,std::string> arg;
0031 public:
0032   args(){
0033 #ifdef TOOLS_MEM
0034     mem::increment(s_class().c_str());
0035 #endif
0036   }
0037   args(int a_argc,char* a_argv[]){
0038 #ifdef TOOLS_MEM
0039     mem::increment(s_class().c_str());
0040 #endif
0041     for(int index=0;index<a_argc;index++) {
0042       std::string _s(a_argv[index]);
0043       std::string::size_type pos = _s.find('=');
0044       if(pos==std::string::npos) {
0045         m_args.push_back(arg(_s,""));
0046       } else {
0047         std::string key = _s.substr(0,pos);
0048         pos++;
0049         std::string value = _s.substr(pos,_s.size()-pos);
0050         m_args.push_back(arg(key,value));
0051       }
0052     }
0053   }
0054   args(const std::vector<std::string>& a_args,bool a_strip = false){
0055 #ifdef TOOLS_MEM
0056     mem::increment(s_class().c_str());
0057 #endif
0058     add(a_args,a_strip);
0059   }
0060   args(const std::vector<arg>& a_args):m_args(a_args){
0061 #ifdef TOOLS_MEM
0062     mem::increment(s_class().c_str());
0063 #endif
0064   }
0065   args(const std::string& a_args,const std::string& a_sep,bool a_strip){
0066 #ifdef TOOLS_MEM
0067     mem::increment(s_class().c_str());
0068 #endif
0069     std::vector<std::string> _args;
0070     words(a_args,a_sep,false,_args);
0071     add(_args,a_strip);
0072   }
0073   virtual ~args(){
0074 #ifdef TOOLS_MEM
0075     mem::decrement(s_class().c_str());
0076 #endif
0077   }
0078 public:
0079   args(const args& a_from):m_args(a_from.m_args){
0080 #ifdef TOOLS_MEM
0081     mem::increment(s_class().c_str());
0082 #endif
0083   }
0084   args& operator=(const args& a_from){
0085     m_args = a_from.m_args;
0086     return *this;
0087   }
0088 public:
0089   const std::vector<arg>& get_args() const {return m_args;}
0090   //std::vector<arg>& get_args() {return m_args;}
0091 
0092   bool is_arg(const std::string& a_string) const {
0093     tools_vforcit(arg,m_args,it) {
0094       if((*it).first==a_string) return true;
0095     }
0096     return false;
0097   }
0098   bool is_empty() const {return m_args.size()?false:true;}
0099   size_t size() const {return m_args.size();}
0100   size_t number() const {return m_args.size();} //back comp.
0101   bool find(const std::string& a_key,std::string& a_value,const std::string& a_def = std::string()) const {
0102     tools_vforcit(arg,m_args,it) {
0103       if((*it).first==a_key) {
0104         a_value = (*it).second;
0105         return true;
0106       }
0107     }
0108     a_value = a_def;
0109     return false;
0110   }
0111 #ifdef TOOLS_DEPRECATED
0112   std::vector<std::string> find(const std::string& a_key) const {
0113     std::vector<std::string> vals;
0114     tools_vforcit(arg,m_args,it) {
0115       if((*it).first==a_key) vals.push_back((*it).second);
0116     }
0117     return vals;
0118   }
0119 #endif
0120   void find(const std::string& a_key,std::vector<std::string>& a_vals,bool a_clear=true) const {
0121     if(a_clear) a_vals.clear();
0122     tools_vforcit(arg,m_args,it) {
0123       if((*it).first==a_key) a_vals.push_back((*it).second);
0124     }
0125   }
0126 
0127   bool find(const std::string& a_string,bool& a_value,const bool& a_def = false) const {
0128     std::string _s;
0129     if(!find(a_string,_s)) {a_value = a_def;return false;}
0130     return to(_s,a_value,a_def);
0131   }
0132   template <class aT>
0133   bool find(const std::string& a_string,aT& a_value,const aT& a_def = aT()) const {
0134     std::string _s;
0135     if(!find(a_string,_s)) {a_value = a_def;return false;}
0136     return to<aT>(_s,a_value,a_def);
0137   }
0138 
0139 #ifdef TOOLS_DEPRECATED
0140   std::vector<std::string> tovector() const {
0141     // Return a vector of string <name=value>
0142     std::vector<std::string> vec;
0143     tools_vforcit(arg,m_args,it) {
0144       std::string _s;
0145       if((*it).second.empty()) {
0146         _s = (*it).first;
0147       } else {
0148         _s = (*it).first;
0149         _s += "=";
0150         _s += (*it).second;
0151       }
0152       vec.push_back(_s);
0153     }
0154     return vec;
0155   }
0156 #endif
0157   void to_vector(std::vector<std::string>& a_vec) const {
0158     // Return a vector of string <name=value>
0159     a_vec.clear();
0160     std::string _s;
0161     tools_vforcit(arg,m_args,it) {
0162       _s = (*it).first;
0163       if((*it).second.size()) {
0164         _s += "=";
0165         _s += (*it).second;
0166       }
0167       a_vec.push_back(_s);
0168     }
0169   }
0170 
0171   bool add(const std::string& a_key,const std::string& a_value = std::string(),bool a_override = true){
0172     if(a_override) {
0173       tools_vforit(arg,m_args,it) {
0174         if((*it).first==a_key) {
0175           (*it).second = a_value;
0176           return true;
0177         }
0178       }
0179     }
0180     if(a_key.empty()) return false;
0181     m_args.push_back(arg(a_key,a_value));
0182     return true;
0183   }
0184 
0185   bool insert_begin(const std::string& a_key,const std::string& a_value = std::string(),bool a_override = true){
0186     if(a_override) {
0187       tools_vforit(arg,m_args,it) {
0188         if((*it).first==a_key) {
0189           (*it).second = a_value;
0190           return true;
0191         }
0192       }
0193     }
0194     if(a_key.empty()) return false;
0195     m_args.insert(m_args.begin(),arg(a_key,a_value));
0196     return true;
0197   }
0198 
0199   void add(const std::vector<std::string>& a_args,bool a_strip = false) {
0200     tools_vforcit(std::string,a_args,it) {
0201       const std::string& sarg = *it;
0202       std::string::size_type pos = sarg.find('=');
0203       if(pos==std::string::npos) {
0204         if(a_strip) {
0205           std::string left = sarg;
0206           strip(left,both,' ');
0207           m_args.push_back(arg(left,""));
0208         } else {
0209           m_args.push_back(arg(sarg,""));
0210         }
0211       } else {
0212         std::string left = sarg.substr(0,pos);
0213         std::string right = sarg.substr((pos+1),sarg.size()-(pos+1));
0214         if(a_strip) {
0215           strip(left,both,' ');
0216           strip(right,both,' ');
0217         }
0218         m_args.push_back(arg(left,right));
0219       }
0220     }
0221   }
0222 
0223   void add_keyvals(const std::vector<std::string>& a_args,bool a_strip = false) {
0224     //a_args must contain an even number of strings.
0225     size_t sz_half = a_args.size()/2;
0226     if((2*sz_half)!=a_args.size()) return;
0227     for(std::vector<std::string>::const_iterator it = a_args.begin();it!=a_args.end();it+=2) {
0228       if(a_strip) {
0229         std::string key = *it;
0230         strip(key,both,' ');
0231         std::string val = *(it+1);
0232         strip(val,both,' ');
0233         m_args.push_back(arg(key,val));
0234       } else {
0235         m_args.push_back(arg(*it,*(it+1)));
0236       }
0237     }
0238   }
0239 
0240   void add(const std::vector<arg>& a_args){
0241     tools_vforcit(arg,a_args,it) m_args.push_back(*it);
0242   }
0243 
0244   void add(const args& a_from){
0245     tools_vforcit(arg,a_from.m_args,it) m_args.push_back(*it);
0246   }
0247 
0248 
0249   int remove(const std::string& a_key){
0250     size_t nbeg = m_args.size();
0251     for(std::vector<arg>::iterator it = m_args.begin();it!=m_args.end();) {
0252       if(a_key==(*it).first) {
0253         it = m_args.erase(it);
0254       } else {
0255         ++it;
0256       }
0257     }
0258     return int(nbeg) - int(m_args.size());
0259   }
0260 
0261   void remove_first(){if(m_args.size()) m_args.erase(m_args.begin());}
0262   void remove_last(){if(m_args.size()) m_args.erase(m_args.end()-1);}
0263 
0264   bool last(std::string& a_key,std::string& a_value) const {
0265     a_key.clear();
0266     a_value.clear();
0267     if(m_args.empty()) return false;
0268     a_key = m_args.back().first;
0269     a_value = m_args.back().second;
0270     return true;
0271   }
0272 
0273   bool prog_name(std::string& a_value) const {
0274     if(m_args.empty()) {a_value.clear();return false;}
0275     if(m_args[0].second.size()) {a_value.clear();return false;}
0276     a_value = m_args[0].first;
0277     return true;
0278   }
0279 
0280   bool file(std::string& a_file) const {
0281     std::string slast;
0282     std::string _s;
0283     if((m_args.size()>1) //first arg is the program name !
0284        && last(slast,_s)
0285        && (slast.find('-')!=0)
0286        && (_s.empty()) ) {
0287       a_file = slast; //Last argument is not an option.
0288       return true;
0289     } else {
0290       a_file.clear();
0291       return false;
0292     }
0293   }
0294 
0295   bool file(std::string& a_file,bool a_remove) {
0296     std::string slast;
0297     std::string _s;
0298     if((m_args.size()>1) //first arg is the program name !
0299        && last(slast,_s)
0300        && (slast.find('-')!=0)
0301        && (_s.empty()) ) {
0302       a_file = slast; //Last argument is not an option.
0303       if(a_remove) m_args.erase(m_args.end()-1);
0304       return true;
0305     } else {
0306       a_file.clear();
0307       return false;
0308     }
0309   }
0310 
0311   void not_hyphens(std::vector<std::string>& a_not_hyphens,bool a_skip_first = false) const {
0312     a_not_hyphens.clear();
0313     // Get the serie of trailing args not beginning with '-'
0314     // and without a value (not of the form [-]xxx=yyy).
0315     // Note that an argument like that in between arguments
0316     // is NOT taken into account.
0317     if(m_args.empty()) return;
0318     std::vector<arg>::const_iterator it = m_args.begin();
0319     if(a_skip_first) it++;
0320     for(;it!=m_args.end();++it) {
0321       if( ((*it).first.find('-')==0) || (*it).second.size() ) {
0322         a_not_hyphens.clear();
0323       } else {
0324         a_not_hyphens.push_back((*it).first);
0325       }
0326     }
0327   }
0328 
0329   void files(std::vector<std::string>& a_files,bool a_skip_first = true) const {  //true and not false as in the upper.
0330     return not_hyphens(a_files,a_skip_first);
0331   }
0332 
0333   bool first_not_hyphen(std::string& a_first,bool a_skip_first = false) const {
0334     std::vector<std::string> _ss;
0335     not_hyphens(_ss,a_skip_first);
0336     if(_ss.empty()) {a_first.clear();return false;}
0337     a_first = _ss[0];
0338     return true;
0339   }
0340 
0341 //bool first_of_files(std::string& a_file,bool a_skip_first) const {return first_of_hyphen(a_file,a_skip_first);}
0342 
0343   bool argcv(int& a_argc,char**& a_argv) const {
0344     // If using with :
0345     //   int argc;
0346     //   char** argv;
0347     //   args.argcv(argc,argv);
0348     // you can delete with :
0349     //   args::delete_argcv(argc,argv);
0350     if(m_args.empty()) {a_argc = 0;a_argv = 0;return true;}
0351     typedef char* _cstr_t;
0352     _cstr_t* av = new _cstr_t[m_args.size()+1];
0353     if(!av) {a_argc = 0;a_argv = 0;return false;}
0354     a_argv = av;
0355     for(std::vector<arg>::const_iterator it = m_args.begin();it!=m_args.end();++it,av++) {
0356       std::string::size_type lf = (*it).first.length();
0357       std::string::size_type ls = (*it).second.length();
0358       std::string::size_type sz = lf;
0359       if(ls) sz += 1 + ls;
0360       char* p = new char[sz+1];
0361       if(!p) {a_argc = 0;a_argv = 0;return false;} //some delete are lacking.
0362       *av = p;
0363      {char* pf = (char*)(*it).first.c_str();
0364       for(std::string::size_type i=0;i<lf;i++,p++,pf++) {*p = *pf;}
0365       *p = 0;}
0366       if(ls) {*p = '=';p++;}
0367      {char* ps = (char*)(*it).second.c_str();
0368       for(std::string::size_type i=0;i<ls;i++,p++,ps++) {*p = *ps;}
0369       *p = 0;}
0370     }
0371     *(a_argv+m_args.size()) = 0;
0372     a_argc = (int)m_args.size();
0373     return true;
0374   }
0375   static void delete_argcv(int& a_argc,char**& a_argv) {
0376     for(int index=0;index<a_argc;index++) delete [] a_argv[index];
0377     delete [] a_argv;
0378     a_argc = 0;
0379     a_argv = 0;
0380   }
0381 
0382   bool known_options(const std::vector<std::string>& a_knowns) const {
0383     tools_vforcit(arg,m_args,it) {
0384       if((*it).first.find('-')==0) { //find '-' at first pos.
0385         bool found = false;
0386         tools_vforcit(std::string,a_knowns,it2) {
0387           if((*it).first==(*it2)) {
0388             found = true;
0389             break;
0390           }
0391         }
0392         if(!found) return false; //one option not in a_knowns.
0393       }
0394     }
0395     return true; //all options are in a_knowns.
0396   }
0397 
0398   bool known_options(const std::string& a_known) const {
0399     tools_vforcit(arg,m_args,it) {
0400       if((*it).first.find('-')==0) { //find '-' at first pos.
0401         if((*it).first!=a_known) return false; //one option not a_known.
0402       }
0403     }
0404     return true; //all options are a_known.
0405   }
0406 
0407 //void remove_string_delimiters_in_keys() {
0408 //  tools_vforit(arg,m_args,it) {
0409 //    if(!rm_quotes((*it).first)) rm_double_quotes((*it).first);
0410 //  }
0411 //}
0412 
0413 //void remove_string_delimiters_in_values() {
0414 //  tools_vforit(arg,m_args,it) {
0415 //    if(!rm_quotes((*it).second)) rm_double_quotes((*it).second);
0416 //  }
0417 //}
0418 
0419   void files_at_end(bool a_skip_first = true) {
0420     // reorder to have "file" arguments at end.
0421     if(m_args.empty()) return;
0422     std::vector<arg> _args;
0423     if(a_skip_first) _args.push_back(*(m_args.begin()));
0424     //first pass :
0425    {std::vector<arg>::const_iterator it = m_args.begin();
0426     if(a_skip_first) it++;
0427     for(;it!=m_args.end();++it) {
0428       if( ((*it).first.find('-')==0) || (*it).second.size() ) {
0429         _args.push_back(*it);
0430       }
0431     }}
0432     //second pass :
0433    {std::vector<arg>::const_iterator it = m_args.begin();
0434     if(a_skip_first) it++;
0435     for(;it!=m_args.end();++it) {
0436       if( ((*it).first.find('-')==0) || (*it).second.size() ) {
0437       } else {
0438         _args.push_back(*it);
0439       }
0440     }}
0441     m_args = _args;
0442   }
0443 
0444   //NOTE : print is a Python keyword.
0445   void dump(std::ostream& a_out,const std::string& a_comment = std::string(),const std::string& a_prefix = std::string()) const {
0446     if(a_comment.size()) a_out << a_comment << std::endl;
0447     tools_vforcit(arg,m_args,it) {
0448       a_out << a_prefix << "key = " << sout((*it).first) << ", value = " << sout((*it).second) << std::endl;
0449     }
0450   }
0451 
0452 public: //backcomp (for Panoramix).
0453   bool isAnArgument(const std::string& a_key) const {return is_arg(a_key);}
0454 protected:
0455   std::vector<arg> m_args;
0456 };
0457 
0458 inline bool check_args(const std::vector<std::string>& a_args,unsigned int a_number,std::ostream& a_out){
0459   if(a_args.size()==a_number) return true;
0460   a_out << "bad argument number."
0461         << " Given " << (unsigned int)a_args.size()
0462         << " whilst " << a_number << " expected."
0463         << std::endl;
0464   return false;
0465 }
0466 
0467 inline bool check_min(const std::vector<std::string>& a_args,unsigned int a_number,std::string& a_last,std::ostream& a_out){
0468   if(a_args.size()>=a_number) {
0469     if(a_number==0) {
0470       if(a_args.empty()) {
0471         a_last.clear();
0472       } else {
0473         a_last = a_args[0];
0474         for(size_t index=1;index<a_args.size();index++) a_last += " " + a_args[index];
0475       }
0476     } else {
0477       a_last = a_args[a_number-1];
0478       for(size_t index=a_number;index<a_args.size();index++) a_last += " " + a_args[index];
0479     }
0480     return true;
0481   }
0482   a_out << "bad argument number."
0483         << " Given " << (unsigned int)a_args.size()
0484         << " whilst at least " << a_number << " expected."
0485         << std::endl;
0486   return false;
0487 }
0488 
0489 inline bool check_min_args(const std::vector<std::string>& aArgs,unsigned int a_number,std::ostream& a_out){
0490   if(aArgs.size()>=a_number) return true;
0491   a_out << "bad argument number."
0492         << " Given " << (unsigned int)aArgs.size()
0493         << " whilst at least " << a_number << " expected."
0494         << std::endl;
0495   return false;
0496 }
0497 
0498 inline bool check_or_args(const std::vector<std::string>& aArgs,unsigned int a_1,unsigned int a_2,std::ostream& a_out){
0499   if((aArgs.size()==a_1)||(aArgs.size()==a_2)) return true;
0500   a_out << "bad argument number."
0501         << " Given " << (unsigned int)aArgs.size()
0502         << " whilst " << a_1 << " or " << a_2 << " expected."
0503         << std::endl;
0504   return false;
0505 }
0506 
0507 inline std::vector<std::string> to(int a_argc,char** a_argv) {
0508   std::vector<std::string> v;
0509   for(int index=0;index<a_argc;index++) v.push_back(a_argv[index]);
0510   return v;
0511 }
0512 
0513 }
0514 
0515 #endif