# # # patch "automate.cc" # from [be40b5df267fa082c976f627521ec513d5bd2745] # to [0d68830ad88c71629db2423f26af42f32e09b5a4] # # patch "mtn_cvs/Makefile.am" # from [8914ec0cf25b42da20d86954db5ca8f0b773ffde] # to [4ac4076d03af937f0f1765e3de741dd1f933c9ca] # # patch "mtn_cvs/options.cc" # from [08e39ee1ceb14377a0bd0f71742992b3f55e3e90] # to [a8cced08e6bd5382c65de20aa793d10dc841c951] # # patch "mtn_cvs/options.hh" # from [4622bbb7a39851eb2155ee9b3ce5357c9f3d99bc] # to [0c9da809849ceed8a68531ef3430de54a64ce9ad] # # patch "mtn_cvs/options_list.hh" # from [e075593e5933f7b87ab35eae1cf0e67c994cb1cc] # to [fada32d2d73004c52b1dd40f8bba773c92b418f3] # ============================================================ --- automate.cc be40b5df267fa082c976f627521ec513d5bd2745 +++ automate.cc 0d68830ad88c71629db2423f26af42f32e09b5a4 @@ -1625,7 +1625,7 @@ AUTOMATE(get_corresponding_path, N_("REV // The ID of the new file (40 digit hex string) // Error conditions: // a runtime exception is thrown if base revision is not available -AUTOMATE(put_file, N_("[BASE-ID] CONTENTS")) +AUTOMATE(put_file, N_("[BASE-ID] CONTENTS"), options::opts::none) { hexenc sha1sum; transaction_guard tr(app.db); @@ -1678,7 +1678,7 @@ AUTOMATE(put_file, N_("[BASE-ID] CONTENT // The ID of the new revision // Error conditions: // none -AUTOMATE(put_revision, N_("SINGLE-EDGE-DATA")) +AUTOMATE(put_revision, N_("SINGLE-EDGE-DATA"), options::opts::none) { if (args.size() != 1) throw usage(name); @@ -1734,7 +1734,7 @@ AUTOMATE(put_revision, N_("SINGLE-EDGE-D // nothing // Error conditions: // none -AUTOMATE(cert, N_("REVISION-ID NAME VALUE")) +AUTOMATE(cert, N_("REVISION-ID NAME VALUE"), options::opts::none) { if (args.size() != 3) throw usage(name); @@ -1759,7 +1759,7 @@ AUTOMATE(cert, N_("REVISION-ID NAME VALU // nothing // Error conditions: // none -AUTOMATE(db_set, N_("DOMAIN NAME VALUE")) +AUTOMATE(db_set, N_("DOMAIN NAME VALUE"), options::opts::none) { if (args.size() != 3) throw usage(name); @@ -1781,7 +1781,7 @@ AUTOMATE(db_set, N_("DOMAIN NAME VALUE") // variable value // Error conditions: // a runtime exception is thrown if the variable is not set -AUTOMATE(db_get, N_("DOMAIN NAME")) +AUTOMATE(db_get, N_("DOMAIN NAME"), options::opts::none) { if (args.size() != 2) throw usage(name); @@ -1832,7 +1832,7 @@ static bool is_synchronized(app_state &a // Error conditions: // a runtime exception is thrown if no synchronized revisions are found // in this domain -AUTOMATE(find_newest_sync, N_("DOMAIN [BRANCH]")) +AUTOMATE(find_newest_sync, N_("DOMAIN [BRANCH]"), options::opts::none) { /* if workspace exists use it to determine branch (and starting revision?) traverse tree upwards to find a synced revision, then traverse tree downwards to find newest revision @@ -1950,7 +1950,7 @@ static sync_map_t get_sync_info(app_stat // sync-data // Error conditions: // a runtime exception is thrown if the data is unavailable -AUTOMATE(get_sync_info, N_("REVISION DOMAIN")) +AUTOMATE(get_sync_info, N_("REVISION DOMAIN"), options::opts::none) { if (args.size() != 2) throw usage(name); @@ -1971,7 +1971,7 @@ AUTOMATE(get_sync_info, N_("REVISION DOM // none // Error conditions: // a runtime exception is thrown if anything goes wrong -AUTOMATE(put_sync_info, N_("REVISION DOMAIN DATA")) +AUTOMATE(put_sync_info, N_("REVISION DOMAIN DATA"), options::opts::none) { if (args.size() != 3) throw usage(name); ============================================================ --- mtn_cvs/Makefile.am 8914ec0cf25b42da20d86954db5ca8f0b773ffde +++ mtn_cvs/Makefile.am 4ac4076d03af937f0f1765e3de741dd1f933c9ca @@ -6,7 +6,7 @@ libmtn_a_SOURCES=../netxx_pipe.cc ../san ../transforms.cc ../vocab.cc ../paths.cc ../charset.cc \ ../simplestring_xform.cc ../constants.cc ../xdelta.cc \ ../commands.cc ../basic_io.cc botan/md5.cpp piece_table.cc \ - ../mtn-sanity.cc ../package_revision.c + ../mtn-sanity.cc ../package_revision.c ../option.cc bin_PROGRAMS = mtn_cvs ============================================================ --- mtn_cvs/options.cc 08e39ee1ceb14377a0bd0f71742992b3f55e3e90 +++ mtn_cvs/options.cc a8cced08e6bd5382c65de20aa793d10dc841c951 @@ -1,125 +1,200 @@ -#include +#include -#include "config.h" -#include "i18n.h" +#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 std::vector; -namespace option -{ - namespace po = boost::program_options; - //using boost::program_options::value; - using boost::program_options::option_description; - using boost::program_options::options_description; +using option::bad_arg_internal; - options_description global_options; - options_description specific_options; +template +bool has_arg() { return true; } +template<> +bool has_arg() { return false; } - no_option none; -// {"no-show-c-function", 0, POPT_ARG_NONE, NULL, OPT_NO_SHOW_ENCLOSER, gettext_noop("another name for --no-show-encloser (for compatibility with GNU diff)"), NULL}, -// {"stdio", 0, POPT_ARG_NONE, NULL, OPT_STDIO, gettext_noop("serve netsync on stdio"), NULL}, -// {"no-transport-auth", 0, POPT_ARG_NONE, NULL, OPT_NO_TRANSPORT_AUTH, gettext_noop("disable transport authentication"), NULL}, -// {"automate-stdio-size", 's', POPT_ARG_LONG, &arglong, OPT_AUTOMATE_STDIO_SIZE, gettext_noop("block size in bytes for \"automate stdio\" output"), NULL}, - struct argless_value : public po::value_semantic - { - std::string name() const { return ""; } - unsigned min_tokens() const { return 0; } - unsigned max_tokens() const { return 0; } - bool is_composing() const { return false; } - void parse(boost::any & value_store, - const std::vector & new_tokens, - bool utf8) const +std::map > & +options::children() +{ + static map > val; + static bool first(true); + if (first) { - value_store = true; +# 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; } - bool apply_default(boost::any & value_store) const + return val; +} + +std::map > & +options::var_membership() +{ + static map > val; + static bool first(true); + if (first) { - return false; +# 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; } - void notify(const boost::any& value_store) const {} - }; - template - struct repeatable_value : public po::value_semantic - { - std::string name() const { return ""; } - unsigned min_tokens() const { return 1; } - unsigned max_tokens() const { return 1; } - bool is_composing() const { return false; } - void parse(boost::any & value_store, - const std::vector & new_tokens, - bool utf8) const + 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) { - value_store = boost::lexical_cast(idx(new_tokens, 0)); + if (*i != opt) + out = out | (*(*i))(); } - bool apply_default(boost::any & value_store) const { return false; } - void notify(const boost::any& value_store) const {} - }; - template - struct repeated_value : public po::value_semantic - { - std::string name() const { return ""; } - unsigned min_tokens() const { return 1; } - unsigned max_tokens() const { return 1; } - bool is_composing() const { return false; } - void parse(boost::any & value_store, - const std::vector & new_tokens, - bool utf8) const + 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) { - if (value_store.empty()) - value_store = std::vector(); - std::vector & val(boost::any_cast&>(value_store)); - val.push_back(boost::lexical_cast(idx(new_tokens, 0))); + (this->*(*i))(); } - bool apply_default(boost::any & value_store) const { return false; } - void notify(const boost::any& value_store) const {} - }; - - template - struct value - { - po::value_semantic * operator ()() - { - return new repeatable_value(); - } - }; - template - struct value > - { - po::value_semantic * operator ()() - { - return new repeated_value(); - } - }; - template<> - struct value - { - po::value_semantic * operator ()() - { - return new argless_value(); - } - }; +} - // the options below are also declared in options.hh for other users. the - // GOPT and COPT defines are just to reduce duplication, maybe there is a - // cleaner way to do the same thing? +options::options_type const & options::opts::none() +{ + static options::options_type val; + return val; +} - const char *localize_string(const char *str) - { - localize_monotone(); - return gettext(str); +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); \ } - // global options -#define GOPT(NAME, OPT, TYPE, DESC) global NAME(new option_description(OPT, value()(), localize_string(DESC))) - // command-specific options -#define COPT(NAME, OPT, TYPE, DESC) specific NAME(new option_description(OPT, value()(), localize_string(DESC))) -#include "options_list.hh" -#undef OPT -#undef COPT +# 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: ============================================================ --- mtn_cvs/options.hh 4622bbb7a39851eb2155ee9b3ce5357c9f3d99bc +++ mtn_cvs/options.hh 0c9da809849ceed8a68531ef3430de54a64ce9ad @@ -1,92 +1,81 @@ #ifndef __OPTIONS_HH__ #define __OPTIONS_HH__ -// Copyright (C) 2005 Richard Levitte -// -// This program is made available under the GNU GPL version 2.0 or -// greater. See the accompanying file COPYING for details. -// -// This program is distributed WITHOUT ANY WARRANTY; without even the -// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. +#include -#include -#include +#include "option.hh" +#include "paths.hh" -#include -#include -namespace option +struct options { - using boost::program_options::option_description; - using boost::program_options::options_description; - using boost::shared_ptr; - using std::string; - using std::vector; + options(); - extern options_description global_options; - extern options_description specific_options; + typedef boost::function reset_function; + typedef option::option option_type; + typedef option::option_set options_type; + typedef options_type const & (*static_options_fun)(); - struct option_base + static std::map > &children(); + static std::map > &var_membership(); + + void reset_optset(static_options_fun opt); + + struct opts { - char const * operator()() { return o->long_name().c_str(); } - shared_ptr ptr() const { return o; } - protected: - option_base(option_description * p) : o(p) {} - shared_ptr o; - }; + static options_type const & none (); + static options_type const & all_options (); +# define OPTSET(name) \ + static options_type const & name (); - template - struct option : public option_base - { - T const & get(boost::program_options::variables_map const & vm) - { - boost::program_options::variable_value const & vv(vm[(*this)()]); - // Workaround for gcc < 3.4. was return vv.as(); - return boost::any_cast(vv.value()); - } - bool given(boost::program_options::variables_map const & vm) - { - return vm.count((*this)()) > 0; - } - protected: - option(option_description * p) : option_base(p) {} +# 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 }; - template - struct global : public option - { - global(option_description * p) : option(p) - { - global_options.add(this->o); - } - }; +# define OPTSET(name) \ + private: \ + void reset_optset_ ## name (); - template - struct specific : public option - { - specific(option_description * p) : option(p) - { - specific_options.add(this->o); - } - }; +# define OPTVAR(optset, type, name, default_) \ + public: \ + type name; \ + void reset_ ## name (); - struct no_option - { - }; - struct nil {}; +#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 (); - extern no_option none; +# define OPTSET_REL(parent, child) - // global options -#define GOPT(NAME, OPT, TYPE, DESC) extern global NAME; - // command-specific options -#define COPT(NAME, OPT, TYPE, DESC) extern specific NAME; -#include "options_list.hh" -#undef GOPT -#undef COPT -} +# 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 @@ -94,5 +83,3 @@ namespace option // 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: - -#endif // __OPTIONS_HH__ ============================================================ --- mtn_cvs/options_list.hh e075593e5933f7b87ab35eae1cf0e67c994cb1cc +++ mtn_cvs/options_list.hh fada32d2d73004c52b1dd40f8bba773c92b418f3 @@ -1,4 +1,14 @@ +#define OPT(name, string, type, default_, description) \ + OPTVAR(name, type, name, default_) \ + OPTION(name, name, has_arg(), string, description) +#define GOPT(name, string, type, default_, description) \ + OPTVAR(globals, type, name, default_) \ + OPTION(globals, name, has_arg(), string, description) + +OPTSET(globals) + + COPT(branch_name, "branch,b", string, N_("select branch cert for operation")); COPT(revision, "revision,r", string, N_("select revision id for operation")); COPT(since, "since", string, N_("set history start for CVS pull"));