| alpar@85 |      1 | /* -*- C++ -*-
 | 
| alpar@85 |      2 |  *
 | 
| alpar@85 |      3 |  * This file is a part of LEMON, a generic C++ optimization library
 | 
| alpar@85 |      4 |  *
 | 
| alpar@85 |      5 |  * Copyright (C) 2003-2008
 | 
| alpar@85 |      6 |  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 | 
| alpar@85 |      7 |  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 | 
| alpar@85 |      8 |  *
 | 
| alpar@85 |      9 |  * Permission to use, modify and distribute this software is granted
 | 
| alpar@85 |     10 |  * provided that this copyright notice appears in all copies. For
 | 
| alpar@85 |     11 |  * precise terms see the accompanying LICENSE file.
 | 
| alpar@85 |     12 |  *
 | 
| alpar@85 |     13 |  * This software is provided "AS IS" with no warranty of any kind,
 | 
| alpar@85 |     14 |  * express or implied, and with no claim as to its suitability for any
 | 
| alpar@85 |     15 |  * purpose.
 | 
| alpar@85 |     16 |  *
 | 
| alpar@85 |     17 |  */
 | 
| alpar@85 |     18 | 
 | 
| alpar@85 |     19 | #include <lemon/arg_parser.h>
 | 
| alpar@85 |     20 | 
 | 
| alpar@85 |     21 | namespace lemon {
 | 
| alpar@85 |     22 | 
 | 
| alpar@85 |     23 |   void ArgParser::_showHelp(void *p)
 | 
| alpar@85 |     24 |   {
 | 
| alpar@85 |     25 |     (static_cast<ArgParser*>(p))->showHelp();
 | 
| alpar@85 |     26 |     exit(1);
 | 
| alpar@85 |     27 |   }
 | 
| alpar@85 |     28 | 
 | 
| alpar@85 |     29 |   ArgParser::ArgParser(int argc, const char **argv) :_argc(argc), _argv(argv),
 | 
| alpar@85 |     30 |                                                      _command_name(argv[0]) {
 | 
| alpar@85 |     31 |     funcOption("-help","Print a short help message",_showHelp,this);
 | 
| alpar@85 |     32 |     synonym("help","-help");
 | 
| alpar@85 |     33 |     synonym("h","-help");
 | 
| alpar@85 |     34 | 
 | 
| alpar@85 |     35 |   }
 | 
| alpar@85 |     36 | 
 | 
| alpar@85 |     37 |   ArgParser::~ArgParser()
 | 
| alpar@85 |     38 |   {
 | 
| alpar@85 |     39 |     for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
 | 
| alpar@85 |     40 |       if(i->second.self_delete)
 | 
| alpar@85 |     41 | 	switch(i->second.type) {
 | 
| alpar@85 |     42 | 	case BOOL:
 | 
| alpar@85 |     43 | 	  delete i->second.bool_p;
 | 
| alpar@85 |     44 | 	  break;
 | 
| alpar@85 |     45 | 	case STRING:
 | 
| alpar@85 |     46 | 	  delete i->second.string_p;
 | 
| alpar@85 |     47 | 	  break;
 | 
| alpar@85 |     48 | 	case DOUBLE:
 | 
| alpar@85 |     49 | 	  delete i->second.double_p;
 | 
| alpar@85 |     50 | 	  break;
 | 
| alpar@85 |     51 | 	case INTEGER:
 | 
| alpar@85 |     52 | 	  delete i->second.int_p;
 | 
| alpar@85 |     53 | 	  break;
 | 
| alpar@85 |     54 | 	case UNKNOWN:
 | 
| alpar@85 |     55 | 	  break;
 | 
| alpar@85 |     56 | 	case FUNC:
 | 
| alpar@85 |     57 | 	  break;
 | 
| alpar@85 |     58 | 	}
 | 
| alpar@85 |     59 |   }
 | 
| alpar@85 |     60 |   
 | 
| alpar@85 |     61 | 
 | 
| alpar@85 |     62 |   ArgParser &ArgParser::intOption(const std::string &name,
 | 
| alpar@85 |     63 | 			       const std::string &help,
 | 
| alpar@85 |     64 | 			       int value, bool obl)
 | 
| alpar@85 |     65 |   {
 | 
| alpar@85 |     66 |     ParData p;
 | 
| alpar@85 |     67 |     p.int_p=new int(value);
 | 
| alpar@85 |     68 |     p.self_delete=true;
 | 
| alpar@85 |     69 |     p.help=help;
 | 
| alpar@85 |     70 |     p.type=INTEGER;
 | 
| alpar@85 |     71 |     p.mandatory=obl;
 | 
| alpar@85 |     72 |     _opts[name]=p;
 | 
| alpar@85 |     73 |     return *this;
 | 
| alpar@85 |     74 |   }
 | 
| alpar@85 |     75 | 
 | 
| alpar@85 |     76 |   ArgParser &ArgParser::doubleOption(const std::string &name,
 | 
| alpar@85 |     77 | 			       const std::string &help,
 | 
| alpar@85 |     78 | 			       double value, bool obl)
 | 
| alpar@85 |     79 |   {
 | 
| alpar@85 |     80 |     ParData p;
 | 
| alpar@85 |     81 |     p.double_p=new double(value);
 | 
| alpar@85 |     82 |     p.self_delete=true;
 | 
| alpar@85 |     83 |     p.help=help;
 | 
| alpar@85 |     84 |     p.type=DOUBLE;
 | 
| alpar@85 |     85 |     p.mandatory=obl;
 | 
| alpar@85 |     86 |     _opts[name]=p;
 | 
| alpar@85 |     87 |     return *this;
 | 
| alpar@85 |     88 |   }
 | 
| alpar@85 |     89 | 
 | 
| alpar@85 |     90 |   ArgParser &ArgParser::boolOption(const std::string &name,
 | 
| alpar@85 |     91 | 			       const std::string &help,
 | 
| alpar@85 |     92 | 			       bool value, bool obl)
 | 
| alpar@85 |     93 |   {
 | 
| alpar@85 |     94 |     ParData p;
 | 
| alpar@85 |     95 |     p.bool_p=new bool(value);
 | 
| alpar@85 |     96 |     p.self_delete=true;
 | 
| alpar@85 |     97 |     p.help=help;
 | 
| alpar@85 |     98 |     p.type=BOOL;
 | 
| alpar@85 |     99 |     p.mandatory=obl;
 | 
| alpar@85 |    100 |     _opts[name]=p;
 | 
| alpar@85 |    101 |     return *this;
 | 
| alpar@85 |    102 |   }
 | 
| alpar@85 |    103 | 
 | 
| alpar@85 |    104 |   ArgParser &ArgParser::stringOption(const std::string &name,
 | 
| alpar@85 |    105 | 			       const std::string &help,
 | 
| alpar@85 |    106 | 			       std::string value, bool obl)
 | 
| alpar@85 |    107 |   {
 | 
| alpar@85 |    108 |     ParData p;
 | 
| alpar@85 |    109 |     p.string_p=new std::string(value);
 | 
| alpar@85 |    110 |     p.self_delete=true;
 | 
| alpar@85 |    111 |     p.help=help;
 | 
| alpar@85 |    112 |     p.type=STRING;
 | 
| alpar@85 |    113 |     p.mandatory=obl;
 | 
| alpar@85 |    114 |     _opts[name]=p;
 | 
| alpar@85 |    115 |     return *this;
 | 
| alpar@85 |    116 |   }
 | 
| alpar@85 |    117 | 
 | 
| alpar@85 |    118 |   ArgParser &ArgParser::refOption(const std::string &name,
 | 
| alpar@85 |    119 | 			       const std::string &help,
 | 
| alpar@85 |    120 | 			       int &ref, bool obl)
 | 
| alpar@85 |    121 |   {
 | 
| alpar@85 |    122 |     ParData p;
 | 
| alpar@85 |    123 |     p.int_p=&ref;
 | 
| alpar@85 |    124 |     p.self_delete=false;
 | 
| alpar@85 |    125 |     p.help=help;
 | 
| alpar@85 |    126 |     p.type=INTEGER;
 | 
| alpar@85 |    127 |     p.mandatory=obl;
 | 
| alpar@85 |    128 |     _opts[name]=p;
 | 
| alpar@85 |    129 |     return *this;
 | 
| alpar@85 |    130 |   }
 | 
| alpar@85 |    131 | 
 | 
| alpar@85 |    132 |   ArgParser &ArgParser::refOption(const std::string &name,
 | 
| alpar@85 |    133 |                                   const std::string &help,
 | 
| alpar@85 |    134 |                                   double &ref, bool obl)
 | 
| alpar@85 |    135 |   {
 | 
| alpar@85 |    136 |     ParData p;
 | 
| alpar@85 |    137 |     p.double_p=&ref;
 | 
| alpar@85 |    138 |     p.self_delete=false;
 | 
| alpar@85 |    139 |     p.help=help;
 | 
| alpar@85 |    140 |     p.type=DOUBLE;
 | 
| alpar@85 |    141 |     p.mandatory=obl;
 | 
| alpar@85 |    142 |     _opts[name]=p;
 | 
| alpar@85 |    143 |     return *this;
 | 
| alpar@85 |    144 |   }
 | 
| alpar@85 |    145 | 
 | 
| alpar@85 |    146 |   ArgParser &ArgParser::refOption(const std::string &name,
 | 
| alpar@85 |    147 |                                   const std::string &help,
 | 
| alpar@85 |    148 |                                   bool &ref, bool obl)
 | 
| alpar@85 |    149 |   {
 | 
| alpar@85 |    150 |     ParData p;
 | 
| alpar@85 |    151 |     p.bool_p=&ref;
 | 
| alpar@85 |    152 |     p.self_delete=false;
 | 
| alpar@85 |    153 |     p.help=help;
 | 
| alpar@85 |    154 |     p.type=BOOL;
 | 
| alpar@85 |    155 |     p.mandatory=obl;
 | 
| alpar@85 |    156 |     _opts[name]=p;
 | 
| alpar@85 |    157 | 
 | 
| alpar@85 |    158 |     ref = false;
 | 
| alpar@85 |    159 | 
 | 
| alpar@85 |    160 |     return *this;
 | 
| alpar@85 |    161 |   }
 | 
| alpar@85 |    162 | 
 | 
| alpar@85 |    163 |   ArgParser &ArgParser::refOption(const std::string &name,
 | 
| alpar@85 |    164 | 			       const std::string &help,
 | 
| alpar@85 |    165 | 			       std::string &ref, bool obl)
 | 
| alpar@85 |    166 |   {
 | 
| alpar@85 |    167 |     ParData p;
 | 
| alpar@85 |    168 |     p.string_p=&ref;
 | 
| alpar@85 |    169 |     p.self_delete=false;
 | 
| alpar@85 |    170 |     p.help=help;
 | 
| alpar@85 |    171 |     p.type=STRING;
 | 
| alpar@85 |    172 |     p.mandatory=obl;
 | 
| alpar@85 |    173 |     _opts[name]=p;
 | 
| alpar@85 |    174 |     return *this;
 | 
| alpar@85 |    175 |   }
 | 
| alpar@85 |    176 | 
 | 
| alpar@85 |    177 |   ArgParser &ArgParser::funcOption(const std::string &name,
 | 
| alpar@85 |    178 | 			       const std::string &help,
 | 
| alpar@85 |    179 | 			       void (*func)(void *),void *data)
 | 
| alpar@85 |    180 |   {
 | 
| alpar@85 |    181 |     ParData p;
 | 
| alpar@85 |    182 |     p.func_p.p=func;
 | 
| alpar@85 |    183 |     p.func_p.data=data;
 | 
| alpar@85 |    184 |     p.self_delete=false;
 | 
| alpar@85 |    185 |     p.help=help;
 | 
| alpar@85 |    186 |     p.type=FUNC;
 | 
| alpar@85 |    187 |     p.mandatory=false;
 | 
| alpar@85 |    188 |     _opts[name]=p;
 | 
| alpar@85 |    189 |     return *this;
 | 
| alpar@85 |    190 |   }
 | 
| alpar@85 |    191 | 
 | 
| alpar@85 |    192 |   ArgParser &ArgParser::optionGroup(const std::string &group,
 | 
| alpar@85 |    193 | 				    const std::string &opt)
 | 
| alpar@85 |    194 |   {
 | 
| alpar@85 |    195 |     Opts::iterator i = _opts.find(opt);
 | 
| alpar@85 |    196 |     LEMON_ASSERT(i!=_opts.end(), "Unknown option: '"+opt+"'");
 | 
| alpar@85 |    197 |     LEMON_ASSERT(!(i->second.ingroup), 
 | 
| alpar@85 |    198 |                  "Option already in option group: '"+opt+"'");
 | 
| alpar@85 |    199 |     GroupData &g=_groups[group];
 | 
| alpar@85 |    200 |     g.opts.push_back(opt);
 | 
| alpar@85 |    201 |     i->second.ingroup=true;
 | 
| alpar@85 |    202 |     return *this;
 | 
| alpar@85 |    203 |   }
 | 
| alpar@85 |    204 | 
 | 
| alpar@85 |    205 |   ArgParser &ArgParser::onlyOneGroup(const std::string &group)
 | 
| alpar@85 |    206 |   {
 | 
| alpar@85 |    207 |     GroupData &g=_groups[group];
 | 
| alpar@85 |    208 |     g.only_one=true;
 | 
| alpar@85 |    209 |     return *this;
 | 
| alpar@85 |    210 |   }
 | 
| alpar@85 |    211 | 
 | 
| alpar@85 |    212 |   ArgParser &ArgParser::synonym(const std::string &syn,
 | 
| alpar@85 |    213 | 				const std::string &opt)
 | 
| alpar@85 |    214 |   {
 | 
| alpar@85 |    215 |     Opts::iterator o = _opts.find(opt);
 | 
| alpar@85 |    216 |     Opts::iterator s = _opts.find(syn);
 | 
| alpar@85 |    217 |     LEMON_ASSERT(o!=_opts.end(), "Unknown option: '"+opt+"'");
 | 
| alpar@85 |    218 |     LEMON_ASSERT(s==_opts.end(), "Option already used: '"+syn+"'");
 | 
| alpar@85 |    219 |     ParData p;
 | 
| alpar@85 |    220 |     p.help=opt;
 | 
| alpar@85 |    221 |     p.mandatory=false;
 | 
| alpar@85 |    222 |     p.syn=true;
 | 
| alpar@85 |    223 |     _opts[syn]=p;
 | 
| alpar@85 |    224 |     o->second.has_syn=true;
 | 
| alpar@85 |    225 |     return *this;
 | 
| alpar@85 |    226 |   }
 | 
| alpar@85 |    227 | 
 | 
| alpar@85 |    228 |   ArgParser &ArgParser::mandatoryGroup(const std::string &group)
 | 
| alpar@85 |    229 |   {
 | 
| alpar@85 |    230 |     GroupData &g=_groups[group];
 | 
| alpar@85 |    231 |     g.mandatory=true;
 | 
| alpar@85 |    232 |     return *this;
 | 
| alpar@85 |    233 |   }
 | 
| alpar@85 |    234 | 
 | 
| alpar@85 |    235 |   ArgParser &ArgParser::other(const std::string &name,
 | 
| alpar@85 |    236 | 			      const std::string &help)
 | 
| alpar@85 |    237 |   {
 | 
| alpar@85 |    238 |     _others_help.push_back(OtherArg(name,help));
 | 
| alpar@85 |    239 |     return *this;
 | 
| alpar@85 |    240 |   }
 | 
| alpar@85 |    241 | 
 | 
| alpar@85 |    242 |   void ArgParser::show(std::ostream &os,Opts::iterator i)
 | 
| alpar@85 |    243 |   {
 | 
| alpar@85 |    244 |     os << "-" << i->first;
 | 
| alpar@85 |    245 |     if(i->second.has_syn)
 | 
| alpar@85 |    246 |       for(Opts::iterator j=_opts.begin();j!=_opts.end();++j)
 | 
| alpar@85 |    247 | 	if(j->second.syn&&j->second.help==i->first)
 | 
| alpar@85 |    248 | 	  os << "|-" << j->first;
 | 
| alpar@85 |    249 |     switch(i->second.type) {
 | 
| alpar@85 |    250 |     case STRING:
 | 
| alpar@85 |    251 |       os << " str";
 | 
| alpar@85 |    252 |       break;
 | 
| alpar@85 |    253 |     case INTEGER:
 | 
| alpar@85 |    254 |       os << " int";
 | 
| alpar@85 |    255 |       break;
 | 
| alpar@85 |    256 |     case DOUBLE:
 | 
| alpar@85 |    257 |       os << " num";
 | 
| alpar@85 |    258 |       break;
 | 
| alpar@85 |    259 |     default:
 | 
| alpar@85 |    260 |       break;
 | 
| alpar@85 |    261 |     }
 | 
| alpar@85 |    262 |   }
 | 
| alpar@85 |    263 | 
 | 
| alpar@85 |    264 |   void ArgParser::show(std::ostream &os,Groups::iterator i)
 | 
| alpar@85 |    265 |   {
 | 
| alpar@85 |    266 |     GroupData::Opts::iterator o=i->second.opts.begin();
 | 
| alpar@85 |    267 |     while(o!=i->second.opts.end()) {
 | 
| alpar@85 |    268 |       show(os,_opts.find(*o));
 | 
| alpar@85 |    269 |       ++o;
 | 
| alpar@85 |    270 |       if(o!=i->second.opts.end()) os<<'|';
 | 
| alpar@85 |    271 |     }
 | 
| alpar@85 |    272 |   }
 | 
| alpar@85 |    273 |     
 | 
| alpar@85 |    274 |   void ArgParser::showHelp(Opts::iterator i)
 | 
| alpar@85 |    275 |   {
 | 
| alpar@85 |    276 |     if(i->second.help.size()==0||i->second.syn) return;
 | 
| alpar@85 |    277 |     std::cerr << "  ";
 | 
| alpar@85 |    278 |     show(std::cerr,i);
 | 
| alpar@85 |    279 |     std::cerr << std::endl;
 | 
| alpar@85 |    280 |     std::cerr << "     " << i->second.help << std::endl;
 | 
| alpar@85 |    281 |   }
 | 
| alpar@85 |    282 |   void ArgParser::showHelp(std::vector<ArgParser::OtherArg>::iterator i)
 | 
| alpar@85 |    283 |   {
 | 
| alpar@85 |    284 |     if(i->help.size()==0) return;
 | 
| alpar@85 |    285 |     std::cerr << "  " << i->name << std::endl
 | 
| alpar@85 |    286 | 	      << "     " << i->help << std::endl;
 | 
| alpar@85 |    287 |   }
 | 
| alpar@85 |    288 |     
 | 
| alpar@85 |    289 |   void ArgParser::shortHelp()
 | 
| alpar@85 |    290 |   {
 | 
| alpar@85 |    291 |     const unsigned int LINE_LEN=77;
 | 
| alpar@85 |    292 |     const std::string indent("    ");
 | 
| alpar@85 |    293 |     std::cerr << "Usage:\n  " << _command_name;
 | 
| alpar@85 |    294 |     int pos=_command_name.size()+2;
 | 
| alpar@85 |    295 |     for(Groups::iterator g=_groups.begin();g!=_groups.end();++g) {
 | 
| alpar@85 |    296 |       std::ostringstream cstr;
 | 
| alpar@85 |    297 |       cstr << ' ';
 | 
| alpar@85 |    298 |       if(!g->second.mandatory) cstr << '[';
 | 
| alpar@85 |    299 |       show(cstr,g);
 | 
| alpar@85 |    300 |       if(!g->second.mandatory) cstr << ']';
 | 
| alpar@85 |    301 |       if(pos+cstr.str().size()>LINE_LEN) {
 | 
| alpar@85 |    302 | 	std::cerr << std::endl << indent;
 | 
| alpar@85 |    303 | 	pos=indent.size();
 | 
| alpar@85 |    304 |       }
 | 
| alpar@85 |    305 |       std::cerr << cstr.str();
 | 
| alpar@85 |    306 |       pos+=cstr.str().size();
 | 
| alpar@85 |    307 |     }
 | 
| alpar@85 |    308 |     for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
 | 
| alpar@85 |    309 |       if(!i->second.ingroup&&!i->second.syn) {
 | 
| alpar@85 |    310 | 	std::ostringstream cstr;
 | 
| alpar@85 |    311 | 	cstr << ' ';
 | 
| alpar@85 |    312 | 	if(!i->second.mandatory) cstr << '[';
 | 
| alpar@85 |    313 | 	show(cstr,i);
 | 
| alpar@85 |    314 | 	if(!i->second.mandatory) cstr << ']';
 | 
| alpar@85 |    315 | 	if(pos+cstr.str().size()>LINE_LEN) {
 | 
| alpar@85 |    316 | 	  std::cerr << std::endl << indent;
 | 
| alpar@85 |    317 | 	  pos=indent.size();
 | 
| alpar@85 |    318 | 	}
 | 
| alpar@85 |    319 | 	std::cerr << cstr.str();
 | 
| alpar@85 |    320 | 	pos+=cstr.str().size();
 | 
| alpar@85 |    321 |       }
 | 
| alpar@85 |    322 |     for(std::vector<OtherArg>::iterator i=_others_help.begin();
 | 
| alpar@85 |    323 | 	i!=_others_help.end();++i)
 | 
| alpar@85 |    324 |       {
 | 
| alpar@85 |    325 | 	std::ostringstream cstr;
 | 
| alpar@85 |    326 | 	cstr << ' ' << i->name;
 | 
| alpar@85 |    327 |       
 | 
| alpar@85 |    328 | 	if(pos+cstr.str().size()>LINE_LEN) {
 | 
| alpar@85 |    329 | 	  std::cerr << std::endl << indent;
 | 
| alpar@85 |    330 | 	  pos=indent.size();
 | 
| alpar@85 |    331 | 	}
 | 
| alpar@85 |    332 | 	std::cerr << cstr.str();
 | 
| alpar@85 |    333 | 	pos+=cstr.str().size();
 | 
| alpar@85 |    334 |       }
 | 
| alpar@85 |    335 |     std::cerr << std::endl;
 | 
| alpar@85 |    336 |   }
 | 
| alpar@85 |    337 |     
 | 
| alpar@85 |    338 |   void ArgParser::showHelp()
 | 
| alpar@85 |    339 |   {
 | 
| alpar@85 |    340 |     shortHelp();
 | 
| alpar@85 |    341 |     std::cerr << "Where:\n";
 | 
| alpar@85 |    342 |     for(std::vector<OtherArg>::iterator i=_others_help.begin();
 | 
| alpar@85 |    343 | 	i!=_others_help.end();++i) showHelp(i);
 | 
| alpar@85 |    344 |     for(Opts::iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
 | 
| alpar@85 |    345 |     exit(1);
 | 
| alpar@85 |    346 |   }
 | 
| alpar@85 |    347 |     
 | 
| alpar@85 |    348 |       
 | 
| alpar@85 |    349 |   void ArgParser::unknownOpt(std::string arg) 
 | 
| alpar@85 |    350 |   {
 | 
| alpar@85 |    351 |     std::cerr << "\nUnknown option: " << arg << "\n";
 | 
| alpar@85 |    352 |     std::cerr << "\nType '" << _command_name <<
 | 
| alpar@85 |    353 |       " --help' to obtain a short summary on the usage.\n\n";
 | 
| alpar@85 |    354 |     exit(1);
 | 
| alpar@85 |    355 |   }
 | 
| alpar@85 |    356 |     
 | 
| alpar@85 |    357 |   void ArgParser::requiresValue(std::string arg, OptType t) 
 | 
| alpar@85 |    358 |   {
 | 
| alpar@85 |    359 |     std::cerr << "Argument '" << arg << "' requires a";
 | 
| alpar@85 |    360 |     switch(t) {
 | 
| alpar@85 |    361 |     case STRING:
 | 
| alpar@85 |    362 |       std::cerr << " string";
 | 
| alpar@85 |    363 |       break;
 | 
| alpar@85 |    364 |     case INTEGER:
 | 
| alpar@85 |    365 |       std::cerr << "n integer";
 | 
| alpar@85 |    366 |       break;
 | 
| alpar@85 |    367 |     case DOUBLE:
 | 
| alpar@85 |    368 |       std::cerr << " floating point";
 | 
| alpar@85 |    369 |       break;
 | 
| alpar@85 |    370 |     default:
 | 
| alpar@85 |    371 |       break;
 | 
| alpar@85 |    372 |     }
 | 
| alpar@85 |    373 |     std::cerr << " value\n\n";
 | 
| alpar@85 |    374 |     showHelp();
 | 
| alpar@85 |    375 |   }
 | 
| alpar@85 |    376 |     
 | 
| alpar@85 |    377 | 
 | 
| alpar@85 |    378 |   void ArgParser::checkMandatories()
 | 
| alpar@85 |    379 |   {
 | 
| alpar@85 |    380 |     bool ok=true;
 | 
| alpar@85 |    381 |     for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
 | 
| alpar@85 |    382 |       if(i->second.mandatory&&!i->second.set) 
 | 
| alpar@85 |    383 | 	{
 | 
| alpar@85 |    384 | 	  if(ok)
 | 
| alpar@85 |    385 | 	    std::cerr << _command_name 
 | 
| alpar@85 |    386 | 		      << ": The following mandatory arguments are missing.\n";
 | 
| alpar@85 |    387 | 	  ok=false;
 | 
| alpar@85 |    388 | 	  showHelp(i);
 | 
| alpar@85 |    389 | 	}
 | 
| alpar@85 |    390 |     for(Groups::iterator i=_groups.begin();i!=_groups.end();++i)
 | 
| alpar@85 |    391 |       if(i->second.mandatory||i->second.only_one)
 | 
| alpar@85 |    392 | 	{
 | 
| alpar@85 |    393 | 	  int set=0;
 | 
| alpar@85 |    394 | 	  for(GroupData::Opts::iterator o=i->second.opts.begin();
 | 
| alpar@85 |    395 | 	      o!=i->second.opts.end();++o)
 | 
| alpar@85 |    396 | 	    if(_opts.find(*o)->second.set) ++set;
 | 
| alpar@85 |    397 | 	  if(i->second.mandatory&&!set) {
 | 
| alpar@85 |    398 | 	    std::cerr << _command_name 
 | 
| alpar@85 |    399 | 		      << ": At least one of the following arguments is mandatory.\n";
 | 
| alpar@85 |    400 | 	    ok=false;
 | 
| alpar@85 |    401 | 	    for(GroupData::Opts::iterator o=i->second.opts.begin();
 | 
| alpar@85 |    402 | 		o!=i->second.opts.end();++o)
 | 
| alpar@85 |    403 | 	      showHelp(_opts.find(*o));
 | 
| alpar@85 |    404 | 	  }
 | 
| alpar@85 |    405 | 	  if(i->second.only_one&&set>1) {
 | 
| alpar@85 |    406 | 	    std::cerr << _command_name 
 | 
| alpar@85 |    407 | 		      << ": At most one of the following arguments can be given.\n";
 | 
| alpar@85 |    408 | 	    ok=false;
 | 
| alpar@85 |    409 | 	    for(GroupData::Opts::iterator o=i->second.opts.begin();
 | 
| alpar@85 |    410 | 		o!=i->second.opts.end();++o)
 | 
| alpar@85 |    411 | 	      showHelp(_opts.find(*o));
 | 
| alpar@85 |    412 | 	  }
 | 
| alpar@85 |    413 | 	}
 | 
| alpar@85 |    414 |     if(!ok) {
 | 
| alpar@85 |    415 |       std::cerr << "\nType '" << _command_name <<
 | 
| alpar@85 |    416 | 	" --help' to obtain a short summary on the usage.\n\n";
 | 
| alpar@85 |    417 |       exit(1);
 | 
| alpar@85 |    418 |     }
 | 
| alpar@85 |    419 |   }
 | 
| alpar@85 |    420 | 
 | 
| alpar@85 |    421 |   ArgParser &ArgParser::parse()
 | 
| alpar@85 |    422 |   {
 | 
| alpar@85 |    423 |     for(int ar=1; ar<_argc; ++ar) {
 | 
| alpar@85 |    424 |       std::string arg(_argv[ar]);
 | 
| alpar@85 |    425 |       if (arg[0] != '-' || arg.size() == 1) {
 | 
| alpar@85 |    426 | 	_file_args.push_back(arg);
 | 
| alpar@85 |    427 |       }
 | 
| alpar@85 |    428 |       else {
 | 
| alpar@85 |    429 | 	Opts::iterator i = _opts.find(arg.substr(1));
 | 
| alpar@85 |    430 | 	if(i==_opts.end()) unknownOpt(arg);
 | 
| alpar@85 |    431 | 	else {
 | 
| alpar@85 |    432 | 	  if(i->second.syn) i=_opts.find(i->second.help);
 | 
| alpar@85 |    433 | 	  ParData &p(i->second);
 | 
| alpar@85 |    434 | 	  if (p.type==BOOL) *p.bool_p=true;
 | 
| alpar@85 |    435 | 	  else if (p.type==FUNC) p.func_p.p(p.func_p.data);
 | 
| alpar@85 |    436 | 	  else if(++ar==_argc) requiresValue(arg, p.type);
 | 
| alpar@85 |    437 | 	  else {
 | 
| alpar@85 |    438 | 	    std::string val(_argv[ar]);
 | 
| alpar@85 |    439 | 	    std::istringstream vals(val);
 | 
| alpar@85 |    440 | 	    switch(p.type) {
 | 
| alpar@85 |    441 | 	    case STRING:
 | 
| alpar@85 |    442 | 	      *p.string_p=val;
 | 
| alpar@85 |    443 | 	      break;
 | 
| alpar@85 |    444 | 	    case INTEGER:
 | 
| alpar@85 |    445 | 	      vals >> *p.int_p;
 | 
| alpar@85 |    446 | 	      break;
 | 
| alpar@85 |    447 | 	    case DOUBLE:
 | 
| alpar@85 |    448 | 	      vals >> *p.double_p;
 | 
| alpar@85 |    449 | 	      break;
 | 
| alpar@85 |    450 | 	    default:
 | 
| alpar@85 |    451 | 	      break;
 | 
| alpar@85 |    452 | 	    }
 | 
| alpar@85 |    453 | 	    if(p.type!=STRING&&(!vals||!vals.eof()))
 | 
| alpar@85 |    454 | 	      requiresValue(arg, p.type);
 | 
| alpar@85 |    455 | 	  }
 | 
| alpar@85 |    456 | 	  p.set = true;
 | 
| alpar@85 |    457 | 	}
 | 
| alpar@85 |    458 |       }
 | 
| alpar@85 |    459 |     }
 | 
| alpar@85 |    460 |     checkMandatories();
 | 
| alpar@85 |    461 | 
 | 
| alpar@85 |    462 |     return *this;
 | 
| alpar@85 |    463 |   }  
 | 
| alpar@85 |    464 | 
 | 
| alpar@85 |    465 | }
 |