26 #ifndef SHORE_PROGRAM_AV_PARSER_HPP__
27 #define SHORE_PROGRAM_AV_PARSER_HPP__
43 #include <boost/utility/enable_if.hpp>
44 #include <boost/type_traits.hpp>
83 opt_base(
const char sh,
const std::string& lo);
85 bool is_option()
const;
87 virtual ~opt_base() {}
90 virtual void *ptr()
const=0;
93 virtual void store_arg(
const char*
const sval,
const bool clear_arg)=0;
96 virtual std::string argdefault_string()
const=0;
99 virtual std::string arg_format()
const=0;
103 std::string typestr(
const T *
const value,
104 typename boost::disable_if<boost::is_integral<T> >::type *dummy_int=0,
105 typename boost::disable_if<boost::is_float<T> >::type *dummy_float=0)
111 std::string typestr(
const T *
const value,
112 typename boost::enable_if<boost::is_integral<T> >::type *dummy_int=0)
118 std::string typestr(
const T *
const value,
119 typename boost::enable_if<boost::is_float<T> >::type *dummy_float=0)
124 inline std::string typestr(
const char *value)
132 return typestr((T*)0)+
"[%]";
136 std::string typestr(
const std::vector<T> *
const value)
138 return typestr((T*)0)+
"[,...]";
142 std::string typestr(
const std::vector<std::vector<T> >*
const value)
144 return typestr((T*)0)+
"[:...][,...]";
148 std::string typestr(
const std::set<T> *
const value)
150 return typestr((T*)0)+
"[,...]";
162 opt_base1(
const char sh,
const std::string& lo,T*
const ptr)
173 return typestr((T*)0);
182 opt_base2(
const char sh,
const std::string& lo,T*
const ptr)
186 virtual void store_arg(
const char*
const sval,
const bool clear_arg)
202 av_option(
const char sh,
const std::string& lo,T*
const ptr)
219 :
public std::runtime_error
236 bool m_posixly_correct;
239 std::string m_currentGroup;
242 std::vector<opt_base *> m_options;
244 std::vector<std::string> m_groupnames;
245 std::map<std::string,std::vector<const opt_base *> > m_opt_groups;
248 std::vector<opt_base *> m_residualargs;
249 std::vector<std::string> m_residualarg_names;
252 std::map<const opt_base *,std::set<const opt_base *> > m_conflicts;
254 std::map<const opt_base *,std::set<const opt_base *> > m_requirements;
257 std::map<std::string,opt_base *> m_havespec;
259 std::map<std::string,std::set<const opt_base *> > m_needspec_con;
261 std::map<std::string,std::set<const opt_base *> > m_needspec_req;
263 std::map<std::string,std::set<const opt_base *> > m_needspec_revreq;
265 std::map<std::string,size_t> m_needspec_residual;
269 std::set<const opt_base *> m_parsedOptions;
271 std::set<const void *> m_alteredValues;
275 std::map<const opt_base *,std::set<const opt_base *> > m_required;
279 std::map<const opt_base *,std::set<const opt_base *> > m_forbidden;
293 bool m_have_aux_info;
299 void setup_dependencies(
300 opt_base *
const opt,
const std::string &conflicts_with);
304 std::set<const opt_base *> alternative_dependencies(
308 void consistency_check();
311 void update_dependencies(
const opt_base *
const opt);
328 const std::string &info,
329 const std::string &aux_info=std::string())
338 const std::string &info,
340 const std::string &aux_info=std::string())
342 add_option(longshort,
"",target,info,def,aux_info);
348 const std::string &conflicts_with,
350 const std::string &info,
351 const std::string &aux_info=std::string())
359 const std::string &conflicts_with,
361 const std::string &info,
363 const std::string &aux_info=std::string())
365 std::vector<std::string> tok=
shore::split(longshort,
',');
371 else if((tok.size()==2)&&(tok[1].
size()==1))
374 throw std::logic_error(
"invalid option specification");
376 const std::vector<opt_base *>::const_iterator conflspec=
377 std::find_if(m_options.begin(),m_options.end(),opt_cmp(opt));
379 if(conflspec!=m_options.end())
380 throw std::logic_error(
"multiple or conflicting option"
382 +opt->
label+
" <-> "+(*conflspec)->label);
386 opt->arg_default=def;
388 setup_dependencies(opt,conflicts_with);
390 m_options.push_back(opt);
392 if(!(aux_info.empty()||m_currentGroup.empty()))
393 m_have_aux_info=
true;
395 if(m_opt_groups[m_currentGroup].empty())
396 m_groupnames.push_back(m_currentGroup);
398 m_opt_groups[m_currentGroup].push_back(opt);
404 const std::string &name,
413 const std::string &name,
414 const std::string &conflicts_with=std::string(),
416 typename boost::disable_if<boost::is_const<T> >::type *dummy=0)
418 m_residualargs.push_back(
new av_option<T>(
char(0),
"",target));
419 m_residualargs.back()->arg_default=def;
420 m_residualargs.back()->id=
'@'+name;
421 m_residualargs.back()->label=name;
422 m_residualarg_names.push_back(name);
424 setup_dependencies(m_residualargs.back(),conflicts_with);
443 void parse_conffile(
const std::string &fn,
const std::string §ion,
444 const std::set<std::string> &noinclude=std::set<std::string>());
465 void set_altered(
const void*
const ptr);
487 template<
class T,
class U>
491 av_option(
const char sh,
const std::string& lo,std::pair<T,U>*
const ptr)
495 virtual void store_arg(
const char*
const sval,
const bool clear_arg)
497 const std::vector<std::string> svv=
shore::split(sval,
',');
500 throw std::runtime_error(
501 "arg is an invalid pair"\
502 " - exactly two values separated by a comma required");
516 return typestr((T*)0)+
','+typestr((U*)0);
525 av_option(
const char sh,
const std::string& lo,std::vector<T>*
const ptr)
531 virtual void store_arg(
const char*
const sval,
const bool clear_arg)
534 const T parsed=shore::parse_value<T>(sval);
551 av_option(
const char sh,
const std::string& lo,std::set<T>*
const ptr)
557 virtual void store_arg(
const char*
const sval,
const bool clear_arg)
560 const T parsed=shore::parse_value<T>(sval);
576 :
public opt_base1<std::vector<std::vector<T> > >
578 av_option(
const char sh,
const std::string& lo,
579 std::vector<std::vector<T> >*
const ptr)
585 virtual void store_arg(
const char*
const sval,
const bool clear_arg)
588 const std::vector<std::string> items=
shore::split(sval,
':');
591 for(
size_t j=0;j<items.size();++j)
593 if(!items[j].empty()) iv.push_back(shore::parse_value<T>(items[j]));
602 std::vector<std::string> ret;
603 for(
size_t i=0;i<opt_base1<std::vector<std::vector<T> > >::valueptr->size();++i)
614 av_option(
const char sh,
const std::string& lo,
bool*
const ptr)
620 virtual void store_arg(
const char*
const sval,
const bool clear_arg)
637 unary(
const int k): n(k) {}
639 unary(
const bool b): n(b?1:0) {}
641 operator bool()
const
657 av_option(
const char sh,
const std::string& lo,unary*
const ptr)
664 virtual void store_arg(
const char*
const sval,
const bool clear_arg)
680 #endif // SHORE_PROGRAM_AV_PARSER_HPP__