Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef tools_args 5 #define tools_args 6 7 #ifdef TOOLS_MEM 8 #include "mem" 9 #include "S_STRING" 10 #endif 11 12 #include "sout" 13 #include "strip" 14 #include "words" 15 #include "sto" 16 #include "forit" 17 #include "mnmx" 18 //#include "squote" 19 20 #include <ostream> 21 22 namespace tools { 23 24 class args { 25 #ifdef TOOLS_MEM 26 public: 27 TOOLS_SCLASS(tools::args) 28 #endif 29 public: 30 typedef std::pair<std::string,std::string> a 31 public: 32 args(){ 33 #ifdef TOOLS_MEM 34 mem::increment(s_class().c_str()); 35 #endif 36 } 37 args(int a_argc,char* a_argv[]){ 38 #ifdef TOOLS_MEM 39 mem::increment(s_class().c_str()); 40 #endif 41 for(int index=0;index<a_argc;index++) { 42 std::string _s(a_argv[index]); 43 std::string::size_type pos = _s.find('=' 44 if(pos==std::string::npos) { 45 m_args.push_back(arg(_s,"")); 46 } else { 47 std::string key = _s.substr(0,pos); 48 pos++; 49 std::string value = _s.substr(pos,_s.size()- 50 m_args.push_back(arg(key,value)); 51 } 52 } 53 } 54 args(const std::vector<std::string>& a_args, 55 #ifdef TOOLS_MEM 56 mem::increment(s_class().c_str()); 57 #endif 58 add(a_args,a_strip); 59 } 60 args(const std::vector<arg>& a_args):m_args( 61 #ifdef TOOLS_MEM 62 mem::increment(s_class().c_str()); 63 #endif 64 } 65 args(const std::string& a_args,const std::st 66 #ifdef TOOLS_MEM 67 mem::increment(s_class().c_str()); 68 #endif 69 std::vector<std::string> _args; 70 words(a_args,a_sep,false,_args); 71 add(_args,a_strip); 72 } 73 virtual ~args(){ 74 #ifdef TOOLS_MEM 75 mem::decrement(s_class().c_str()); 76 #endif 77 } 78 public: 79 args(const args& a_from):m_args(a_from.m_arg 80 #ifdef TOOLS_MEM 81 mem::increment(s_class().c_str()); 82 #endif 83 } 84 args& operator=(const args& a_from){ 85 m_args = a_from.m_args; 86 return *this; 87 } 88 public: 89 const std::vector<arg>& get_args() const {re 90 //std::vector<arg>& get_args() {return m_arg 91 92 bool is_arg(const std::string& a_string) con 93 tools_vforcit(arg,m_args,it) { 94 if((*it).first==a_string) return true; 95 } 96 return false; 97 } 98 bool is_empty() const {return m_args.size()? 99 size_t size() const {return m_args.size();} 100 size_t number() const {return m_args.size(); 101 bool find(const std::string& a_key,std::stri 102 tools_vforcit(arg,m_args,it) { 103 if((*it).first==a_key) { 104 a_value = (*it).second; 105 return true; 106 } 107 } 108 a_value = a_def; 109 return false; 110 } 111 #ifdef TOOLS_DEPRECATED 112 std::vector<std::string> find(const std::str 113 std::vector<std::string> vals; 114 tools_vforcit(arg,m_args,it) { 115 if((*it).first==a_key) vals.push_back((* 116 } 117 return vals; 118 } 119 #endif 120 void find(const std::string& a_key,std::vect 121 if(a_clear) a_vals.clear(); 122 tools_vforcit(arg,m_args,it) { 123 if((*it).first==a_key) a_vals.push_back( 124 } 125 } 126 127 bool find(const std::string& a_string,bool& 128 std::string _s; 129 if(!find(a_string,_s)) {a_value = a_def;re 130 return to(_s,a_value,a_def); 131 } 132 template <class aT> 133 bool find(const std::string& a_string,aT& a_ 134 std::string _s; 135 if(!find(a_string,_s)) {a_value = a_def;re 136 return to<aT>(_s,a_value,a_def); 137 } 138 139 #ifdef TOOLS_DEPRECATED 140 std::vector<std::string> tovector() const { 141 // Return a vector of string <name=value> 142 std::vector<std::string> vec; 143 tools_vforcit(arg,m_args,it) { 144 std::string _s; 145 if((*it).second.empty()) { 146 _s = (*it).first; 147 } else { 148 _s = (*it).first; 149 _s += "="; 150 _s += (*it).second; 151 } 152 vec.push_back(_s); 153 } 154 return vec; 155 } 156 #endif 157 void to_vector(std::vector<std::string>& a_v 158 // Return a vector of string <name=value> 159 a_vec.clear(); 160 std::string _s; 161 tools_vforcit(arg,m_args,it) { 162 _s = (*it).first; 163 if((*it).second.size()) { 164 _s += "="; 165 _s += (*it).second; 166 } 167 a_vec.push_back(_s); 168 } 169 } 170 171 bool add(const std::string& a_key,const std: 172 if(a_override) { 173 tools_vforit(arg,m_args,it) { 174 if((*it).first==a_key) { 175 (*it).second = a_value; 176 return true; 177 } 178 } 179 } 180 if(a_key.empty()) return false; 181 m_args.push_back(arg(a_key,a_value)); 182 return true; 183 } 184 185 bool insert_begin(const std::string& a_key,c 186 if(a_override) { 187 tools_vforit(arg,m_args,it) { 188 if((*it).first==a_key) { 189 (*it).second = a_value; 190 return true; 191 } 192 } 193 } 194 if(a_key.empty()) return false; 195 m_args.insert(m_args.begin(),arg(a_key,a_v 196 return true; 197 } 198 199 void add(const std::vector<std::string>& a_a 200 tools_vforcit(std::string,a_args,it) { 201 const std::string& sarg = *it; 202 std::string::size_type pos = sarg.find(' 203 if(pos==std::string::npos) { 204 if(a_strip) { 205 std::string left = sarg; 206 strip(left,both,' '); 207 m_args.push_back(arg(left,"")); 208 } else { 209 m_args.push_back(arg(sarg,"")); 210 } 211 } else { 212 std::string left = sarg.substr(0,pos); 213 std::string right = sarg.substr((pos+1 214 if(a_strip) { 215 strip(left,both,' '); 216 strip(right,both,' '); 217 } 218 m_args.push_back(arg(left,right)); 219 } 220 } 221 } 222 223 void add_keyvals(const std::vector<std::stri 224 //a_args must contain an even number of st 225 size_t sz_half = a_args.size()/2; 226 if((2*sz_half)!=a_args.size()) return; 227 for(std::vector<std::string>::const_iterat 228 if(a_strip) { 229 std::string key = *it; 230 strip(key,both,' '); 231 std::string val = *(it+1); 232 strip(val,both,' '); 233 m_args.push_back(arg(key,val)); 234 } else { 235 m_args.push_back(arg(*it,*(it+1))); 236 } 237 } 238 } 239 240 void add(const std::vector<arg>& a_args){ 241 tools_vforcit(arg,a_args,it) m_args.push_b 242 } 243 244 void add(const args& a_from){ 245 tools_vforcit(arg,a_from.m_args,it) m_args 246 } 247 248 249 int remove(const std::string& a_key){ 250 size_t nbeg = m_args.size(); 251 for(std::vector<arg>::iterator it = m_args 252 if(a_key==(*it).first) { 253 it = m_args.erase(it); 254 } else { 255 ++it; 256 } 257 } 258 return int(nbeg) - int(m_args.size()); 259 } 260 261 void remove_first(){if(m_args.size()) m_args 262 void remove_last(){if(m_args.size()) m_args. 263 264 bool last(std::string& a_key,std::string& a_ 265 a_key.clear(); 266 a_value.clear(); 267 if(m_args.empty()) return false; 268 a_key = m_args.back().first; 269 a_value = m_args.back().second; 270 return true; 271 } 272 273 bool prog_name(std::string& a_value) const { 274 if(m_args.empty()) {a_value.clear();return 275 if(m_args[0].second.size()) {a_value.clear 276 a_value = m_args[0].first; 277 return true; 278 } 279 280 bool file(std::string& a_file) const { 281 std::string slast; 282 std::string _s; 283 if((m_args.size()>1) //first arg is the pr 284 && last(slast,_s) 285 && (slast.find('-')!=0) 286 && (_s.empty()) ) { 287 a_file = slast; //Last argument is not a 288 return true; 289 } else { 290 a_file.clear(); 291 return false; 292 } 293 } 294 295 bool file(std::string& a_file,bool a_remove) 296 std::string slast; 297 std::string _s; 298 if((m_args.size()>1) //first arg is the pr 299 && last(slast,_s) 300 && (slast.find('-')!=0) 301 && (_s.empty()) ) { 302 a_file = slast; //Last argument is not a 303 if(a_remove) m_args.erase(m_args.end()-1 304 return true; 305 } else { 306 a_file.clear(); 307 return false; 308 } 309 } 310 311 void not_hyphens(std::vector<std::string>& a 312 a_not_hyphens.clear(); 313 // Get the serie of trailing args not begi 314 // and without a value (not of the form [- 315 // Note that an argument like that in betw 316 // is NOT taken into account. 317 if(m_args.empty()) return; 318 std::vector<arg>::const_iterator it = m_ar 319 if(a_skip_first) it++; 320 for(;it!=m_args.end();++it) { 321 if( ((*it).first.find('-')==0) || (*it). 322 a_not_hyphens.clear(); 323 } else { 324 a_not_hyphens.push_back((*it).first); 325 } 326 } 327 } 328 329 void files(std::vector<std::string>& a_files 330 return not_hyphens(a_files,a_skip_first); 331 } 332 333 bool first_not_hyphen(std::string& a_first,b 334 std::vector<std::string> _ss; 335 not_hyphens(_ss,a_skip_first); 336 if(_ss.empty()) {a_first.clear();return fa 337 a_first = _ss[0]; 338 return true; 339 } 340 341 //bool first_of_files(std::string& a_file,bool 342 343 bool argcv(int& a_argc,char**& a_argv) const 344 // If using with : 345 // int argc; 346 // char** argv; 347 // args.argcv(argc,argv); 348 // you can delete with : 349 // args::delete_argcv(argc,argv); 350 if(m_args.empty()) {a_argc = 0;a_argv = 0; 351 typedef char* _cstr_t; 352 _cstr_t* av = new _cstr_t[m_args.size()+1] 353 if(!av) {a_argc = 0;a_argv = 0;return fals 354 a_argv = av; 355 for(std::vector<arg>::const_iterator it = 356 std::string::size_type lf = (*it).first. 357 std::string::size_type ls = (*it).second 358 std::string::size_type sz = lf; 359 if(ls) sz += 1 + ls; 360 char* p = new char[sz+1]; 361 if(!p) {a_argc = 0;a_argv = 0;return fal 362 *av = p; 363 {char* pf = (char*)(*it).first.c_str(); 364 for(std::string::size_type i=0;i<lf;i++, 365 *p = 0;} 366 if(ls) {*p = '=';p++;} 367 {char* ps = (char*)(*it).second.c_str(); 368 for(std::string::size_type i=0;i<ls;i++, 369 *p = 0;} 370 } 371 *(a_argv+m_args.size()) = 0; 372 a_argc = (int)m_args.size(); 373 return true; 374 } 375 static void delete_argcv(int& a_argc,char**& 376 for(int index=0;index<a_argc;index++) dele 377 delete [] a_argv; 378 a_argc = 0; 379 a_argv = 0; 380 } 381 382 bool known_options(const std::vector<std::st 383 tools_vforcit(arg,m_args,it) { 384 if((*it).first.find('-')==0) { //find '- 385 bool found = false; 386 tools_vforcit(std::string,a_knowns,it2 387 if((*it).first==(*it2)) { 388 found = true; 389 break; 390 } 391 } 392 if(!found) return false; //one option 393 } 394 } 395 return true; //all options are in a_knowns 396 } 397 398 bool known_options(const std::string& a_know 399 tools_vforcit(arg,m_args,it) { 400 if((*it).first.find('-')==0) { //find '- 401 if((*it).first!=a_known) return false; 402 } 403 } 404 return true; //all options are a_known. 405 } 406 407 //void remove_string_delimiters_in_keys() { 408 // tools_vforit(arg,m_args,it) { 409 // if(!rm_quotes((*it).first)) rm_double_qu 410 // } 411 //} 412 413 //void remove_string_delimiters_in_values() { 414 // tools_vforit(arg,m_args,it) { 415 // if(!rm_quotes((*it).second)) rm_double_q 416 // } 417 //} 418 419 void files_at_end(bool a_skip_first = true) 420 // reorder to have "file" arguments at end 421 if(m_args.empty()) return; 422 std::vector<arg> _args; 423 if(a_skip_first) _args.push_back(*(m_args. 424 //first pass : 425 {std::vector<arg>::const_iterator it = m_ar 426 if(a_skip_first) it++; 427 for(;it!=m_args.end();++it) { 428 if( ((*it).first.find('-')==0) || (*it). 429 _args.push_back(*it); 430 } 431 }} 432 //second pass : 433 {std::vector<arg>::const_iterator it = m_ar 434 if(a_skip_first) it++; 435 for(;it!=m_args.end();++it) { 436 if( ((*it).first.find('-')==0) || (*it). 437 } else { 438 _args.push_back(*it); 439 } 440 }} 441 m_args = _args; 442 } 443 444 //NOTE : print is a Python keyword. 445 void dump(std::ostream& a_out,const std::str 446 if(a_comment.size()) a_out << a_comment << 447 tools_vforcit(arg,m_args,it) { 448 a_out << a_prefix << "key = " << sout((* 449 } 450 } 451 452 public: //backcomp (for Panoramix). 453 bool isAnArgument(const std::string& a_key) 454 protected: 455 std::vector<arg> m_args; 456 }; 457 458 inline bool check_args(const std::vector<std:: 459 if(a_args.size()==a_number) return true; 460 a_out << "bad argument number." 461 << " Given " << (unsigned int)a_args.s 462 << " whilst " << a_number << " expecte 463 << std::endl; 464 return false; 465 } 466 467 inline bool check_min(const std::vector<std::s 468 if(a_args.size()>=a_number) { 469 if(a_number==0) { 470 if(a_args.empty()) { 471 a_last.clear(); 472 } else { 473 a_last = a_args[0]; 474 for(size_t index=1;index<a_args.size() 475 } 476 } else { 477 a_last = a_args[a_number-1]; 478 for(size_t index=a_number;index<a_args.s 479 } 480 return true; 481 } 482 a_out << "bad argument number." 483 << " Given " << (unsigned int)a_args.s 484 << " whilst at least " << a_number << 485 << std::endl; 486 return false; 487 } 488 489 inline bool check_min_args(const std::vector<s 490 if(aArgs.size()>=a_number) return true; 491 a_out << "bad argument number." 492 << " Given " << (unsigned int)aArgs.si 493 << " whilst at least " << a_number << 494 << std::endl; 495 return false; 496 } 497 498 inline bool check_or_args(const std::vector<st 499 if((aArgs.size()==a_1)||(aArgs.size()==a_2)) 500 a_out << "bad argument number." 501 << " Given " << (unsigned int)aArgs.si 502 << " whilst " << a_1 << " or " << a_2 503 << std::endl; 504 return false; 505 } 506 507 inline std::vector<std::string> to(int a_argc, 508 std::vector<std::string> v; 509 for(int index=0;index<a_argc;index++) v.push 510 return v; 511 } 512 513 } 514 515 #endif