# # # add_file "options.cc" # content [a8cced08e6bd5382c65de20aa793d10dc841c951] # # add_file "options.hh" # content [0c9da809849ceed8a68531ef3430de54a64ce9ad] # ============================================================ --- options.cc a8cced08e6bd5382c65de20aa793d10dc841c951 +++ options.cc a8cced08e6bd5382c65de20aa793d10dc841c951 @@ -0,0 +1,200 @@ + +#include + +#include +#include + +#include "charset.hh" +#include "options.hh" +#include "platform.hh" +#include "sanity.hh" +#include "ui.hh" + +using std::list; +using std::map; +using std::set; +using std::string; + +using option::bad_arg_internal; + +template +bool has_arg() { return true; } +template<> +bool has_arg() { return false; } + + + +std::map > & +options::children() +{ + static map > val; + static bool first(true); + if (first) + { +# define OPTSET(name) \ + val[&options::opts::all_options].insert(&options::opts::name); +# define OPTVAR(optset, type, name, default_) +# define OPTION(optset, name, hasarg, optstring, description) \ + val[&options::opts:: optset].insert(&options::opts:: name); \ + val[&options::opts::all_options].insert(&options::opts::name); +# define OPTSET_REL(parent, child) \ + val[&options::opts:: parent].insert(&options::opts:: child); + +# include "options_list.hh" + +# undef OPTSET +# undef OPTVAR +# undef OPTION +# undef OPTSET_REL + + first = false; + } + return val; +} + +std::map > & +options::var_membership() +{ + static map > val; + static bool first(true); + if (first) + { +# define OPTSET(name) +# define OPTVAR(optset, type, name, default_) \ + val[&opts:: optset ].push_back(&options::reset_ ## name ); +# define OPTION(optset, name, hasarg, optstring, description) +# define OPTSET_REL(parent, child) + +# include "options_list.hh" + +# undef OPTSET +# undef OPTVAR +# undef OPTION +# undef OPTSET_REL + + first = false; + } + return val; +} + + +options::options() +{ +# define OPTSET(name) +# define OPTVAR(group, type, name, default_) \ + name = type ( default_ ); +# define OPTION(optset, name, hasarg, optstring, description) \ + name ## _given = false; +# define OPTSET_REL(parent, child) + +# include "options_list.hh" + +# undef OPTSET +# undef OPTVAR +# undef OPTION +# undef OPTSET_REL +} + +static options::options_type +collect_children(options::static_options_fun opt) +{ + options::options_type out; + set const & ch = options::children()[opt]; + for (set::const_iterator i = ch.begin(); + i != ch.end(); ++i) + { + if (*i != opt) + out = out | (*(*i))(); + } + return out; +} + +void options::reset_optset(options::static_options_fun opt) +{ + list const & vars = var_membership()[opt]; + for (list::const_iterator i = vars.begin(); + i != vars.end(); ++i) + { + (this->*(*i))(); + } +} + +options::options_type const & options::opts::none() +{ + static options::options_type val; + return val; +} + +options::options_type const & options::opts::all_options() +{ + static options::options_type val = collect_children(&options::opts::all_options); + return val; +} + +# define OPTSET(name) \ + options::options_type const & options::opts::name() \ + { \ + static options::options_type val = \ + collect_children(&options::opts::name) \ + | options::option_type("", #name, false, 0, \ + &options::reset_optset_ ## name ); \ + return val; \ + } \ + void options::reset_optset_ ## name () \ + { \ + reset_optset(&opts:: name); \ + } + +# define OPTVAR(optset, type, name, default_) \ + void options::reset_ ## name () \ + { \ + name = type ( default_ ); \ + } + +# define OPTION(optset, name, hasarg, optstring, description) \ + options::options_type const & options::opts::name() \ + { \ + static options::options_type val(optstring, \ + gettext(description), hasarg, \ + &options::set_ ## name , \ + &options::reset_opt_ ## name ); \ + return val; \ + } \ + void options::reset_opt_ ## name () \ + { \ + name ## _given = false; \ + reset_optset(&opts:: name); \ + } \ + void options::set_ ## name (std::string arg) \ + { \ + name ## _given = true; \ + real_set_ ## name (arg); \ + } \ + void options::real_set_ ## name (std::string arg) + +# define OPTSET_REL(parent, child) + +#define option_bodies +# include "options_list.hh" +#undef option_bodies + +# undef OPTSET +# undef OPTVAR +# undef OPTION +# undef OPTSET_REL + + +option::option_set +operator | (option::option_set const & opts, + option::option_set const & (*fun)()) +{ + return opts | fun(); +} + +// Local Variables: +// mode: C++ +// fill-column: 76 +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: ============================================================ --- options.hh 0c9da809849ceed8a68531ef3430de54a64ce9ad +++ options.hh 0c9da809849ceed8a68531ef3430de54a64ce9ad @@ -0,0 +1,85 @@ +#ifndef __OPTIONS_HH__ +#define __OPTIONS_HH__ + +#include + +#include "option.hh" +#include "paths.hh" + + +struct options +{ + options(); + + typedef boost::function reset_function; + typedef option::option option_type; + typedef option::option_set options_type; + typedef options_type const & (*static_options_fun)(); + + static std::map > &children(); + static std::map > &var_membership(); + + void reset_optset(static_options_fun opt); + + struct opts + { + static options_type const & none (); + static options_type const & all_options (); +# define OPTSET(name) \ + static options_type const & name (); + +# define OPTVAR(optset, type, name, default_) + +#define OPTION(optset, name, hasarg, optstring, description) \ + static options_type const & name (); + +# define OPTSET_REL(parent, child) + +# include "options_list.hh" + +# undef OPTSET +# undef OPTVAR +# undef OPTION +# undef OPTSET_REL + }; + +# define OPTSET(name) \ + private: \ + void reset_optset_ ## name (); + +# define OPTVAR(optset, type, name, default_) \ + public: \ + type name; \ + void reset_ ## name (); + +#define OPTION(optset, name, hasarg, optstring, description) \ + public: \ + bool name ## _given; \ +private: \ + void set_ ## name (std::string arg); \ + void real_set_ ## name (std::string arg); \ + void reset_opt_ ## name (); + +# define OPTSET_REL(parent, child) + +# include "options_list.hh" + +# undef OPTSET +# undef OPTVAR +# undef OPTION +# undef OPTSET_REL +}; + +option::option_set +operator | (option::option_set const & opts, + option::option_set const & (*fun)()); + +#endif + +// Local Variables: +// mode: C++ +// fill-column: 76 +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: