# # # patch "cmd.cc" # from [31533581998105a537eb56e3ce3e8c5b11321708] # to [163f99ce43db2eeb334a47f9ce797a09e69509db] # # patch "monotone.cc" # from [1fe24aeec288b0cf1d6f47dfb6c14f3bb577c307] # to [dfa276b3970ae7d510d87f3aa6629225098c5fb3] # # patch "option.cc" # from [b1f720ac084d118c697802eb3c1438124995da97] # to [00a03c5eea5c4c3303ddcdfe73e0bb2e4e1013a6] # # patch "option.hh" # from [43d24f19f37541c44dc7de3c8a6d5e5965a0aaf7] # to [59c63eefa82a518b4fdc17efba28e5f50a5711e2] # # patch "options_list.hh" # from [2accfaf2fdfe2dd34913cd58e054ef582f4d3124] # to [06e06d0b13755fb99fcc1d7b91bac97ba7963bf0] # ============================================================ --- cmd.cc 31533581998105a537eb56e3ce3e8c5b11321708 +++ cmd.cc 163f99ce43db2eeb334a47f9ce797a09e69509db @@ -121,7 +121,8 @@ namespace commands { = (options::opts::globals() | cmd->opts()) .instantiate(&app.opts); - optset.from_command_line(app.reset_info.default_args, false); + optset.from_command_line(app.reset_info.default_args, + option::concrete_option_set::xargs_forbidden); if (subcmd) { @@ -130,7 +131,8 @@ namespace commands { subcmd_defaults); (options::opts::globals() | subcmd->opts()) .instantiate(&app.opts) - .from_command_line(subcmd_defaults, false); + .from_command_line(subcmd_defaults, + option::concrete_option_set::xargs_forbidden); } // at this point we process the data from _MTN/options if @@ -141,7 +143,8 @@ namespace commands { workspace::get_options(app.opts); } - optset.from_command_line(app.reset_info.cmdline_args, false); + optset.from_command_line(app.reset_info.cmdline_args, + option::concrete_option_set::xargs_forbidden); if (subcmd) { @@ -152,7 +155,8 @@ namespace commands { if (!separate_params) { /* the first argument here is only ever modified if the second is 'true' */ - subcmd_optset.from_command_line(const_cast(subcmd_cmdline), false); + subcmd_optset.from_command_line(const_cast(subcmd_cmdline), + option::concrete_option_set::xargs_forbidden); } else { ============================================================ --- monotone.cc 1fe24aeec288b0cf1d6f47dfb6c14f3bb577c307 +++ monotone.cc dfa276b3970ae7d510d87f3aa6629225098c5fb3 @@ -185,7 +185,9 @@ cpp_main(int argc, char ** argv) app.reset_info.cmdline_args = args; options::opts::all_options().instantiate(&app.opts) - .from_command_line(app.reset_info.cmdline_args); + .from_command_line(app.reset_info.cmdline_args, + option::concrete_option_set::xargs_allowed, + option::concrete_option_set::allow_duplicates); if (app.opts.version_given) { ============================================================ --- option.cc b1f720ac084d118c697802eb3c1438124995da97 +++ option.cc 00a03c5eea5c4c3303ddcdfe73e0bb2e4e1013a6 @@ -264,12 +264,14 @@ tokenize_for_command_line(string const & to.push_back(arg_type(cur, origin::user)); } -void concrete_option_set::from_command_line(int argc, char const * const * argv) +void concrete_option_set::from_command_line(int argc, + char const * const * argv, + concrete_option_set::option_parse_type ty) { args_vector arguments; for (int i = 1; i < argc; ++i) arguments.push_back(arg_type(argv[i], origin::user)); - from_command_line(arguments, true); + from_command_line(arguments, xargs_allowed, ty); } static concrete_option const & @@ -282,27 +284,55 @@ getopt(map cons throw unknown_option(name); } +typedef pair::iterator, bool> by_name_res_type; +static void check_by_name_insertion(by_name_res_type const & res, + concrete_option const & opt, + concrete_option_set::option_parse_type ty) +{ + switch (ty) + { + case concrete_option_set::allow_duplicates: + if (!res.second) + { + string const & name = res.first->first; + concrete_option const & them = res.first->second; + bool const i_have_arg = (name != opt.cancelname && opt.has_arg); + bool const they_have_arg = (name != them.cancelname && them.has_arg); + I(i_have_arg == they_have_arg); + } + break; + case concrete_option_set::forbid_duplicates: + I(res.second); + break; + } +} + static map -get_by_name(std::set const & options) +get_by_name(std::set const & options, + concrete_option_set::option_parse_type ty) { map by_name; for (std::set::const_iterator i = options.begin(); i != options.end(); ++i) { if (!i->longname.empty()) - I(by_name.insert(make_pair(i->longname, *i)).second); + check_by_name_insertion(by_name.insert(make_pair(i->longname, *i)), + *i, ty); if (!i->shortname.empty()) - I(by_name.insert(make_pair(i->shortname, *i)).second); + check_by_name_insertion(by_name.insert(make_pair(i->shortname, *i)), + *i, ty); if (!i->cancelname.empty()) - I(by_name.insert(make_pair(i->cancelname, *i)).second); + check_by_name_insertion(by_name.insert(make_pair(i->cancelname, *i)), + *i, ty); } return by_name; } void concrete_option_set::from_command_line(args_vector & args, - bool allow_xargs) + allow_xargs_t allow_xargs, + concrete_option_set::option_parse_type ty) { - map by_name = get_by_name(options); + map by_name = get_by_name(options, ty); bool seen_dashdash = false; for (args_vector::size_type i = 0; i < args.size(); ++i) @@ -317,7 +347,7 @@ void concrete_option_set::from_command_l if (!seen_dashdash) { seen_dashdash = true; - allow_xargs = false; + allow_xargs = xargs_forbidden; continue; } name = "--"; @@ -382,7 +412,7 @@ void concrete_option_set::from_command_l is_cancel = false; } - if (allow_xargs && (name == "xargs" || name == "@")) + if (allow_xargs == xargs_allowed && (name == "xargs" || name == "@")) { // expand the --xargs in place data dat; @@ -430,9 +460,10 @@ void concrete_option_set::from_command_l } } -void concrete_option_set::from_key_value_pairs(vector > const & keyvals) +void concrete_option_set::from_key_value_pairs(vector > const & keyvals, + concrete_option_set::option_parse_type ty) { - map by_name = get_by_name(options); + map by_name = get_by_name(options, ty); for (vector >::const_iterator i = keyvals.begin(); i != keyvals.end(); ++i) @@ -441,13 +472,23 @@ void concrete_option_set::from_key_value arg_type const & value(arg_type(i->second, origin::user)); concrete_option o = getopt(by_name, key); + bool const is_cancel = (key == o.cancelname); try { if (o.deprecated) W(F("deprated option '%s' used: %s") % i->first % gettext(o.deprecated)); - if (o.setter) - o.setter(value()); + + if (!is_cancel) + { + if (o.setter) + o.setter(value()); + } + else + { + if (o.resetter) + o.resetter(); + } } catch (boost::bad_lexical_cast) { ============================================================ --- option.hh 43d24f19f37541c44dc7de3c8a6d5e5965a0aaf7 +++ option.hh 59c63eefa82a518b4fdc17efba28e5f50a5711e2 @@ -138,9 +138,18 @@ namespace option { unsigned int & maxnamelen, bool show_hidden /*no way to see deprecated*/) const; - void from_command_line(args_vector & args, bool allow_xargs = true); - void from_command_line(int argc, char const * const * argv); - void from_key_value_pairs(std::vector > const & keyvals); + enum option_parse_type { forbid_duplicates, allow_duplicates }; + enum allow_xargs_t { xargs_forbidden, xargs_allowed }; + void from_command_line(args_vector & args, + allow_xargs_t allow_xargs = xargs_allowed, + option_parse_type ty = forbid_duplicates); + void from_command_line(int argc, + char const * const * argv, + option_parse_type ty = forbid_duplicates); + typedef std::pair key_value_pair; + typedef std::vector key_value_list; + void from_key_value_pairs(key_value_list const & keyvals, + option_parse_type ty = forbid_duplicates); }; concrete_option_set operator | (concrete_option const & a, concrete_option const & b); ============================================================ --- options_list.hh 2accfaf2fdfe2dd34913cd58e054ef582f4d3124 +++ options_list.hh 06e06d0b13755fb99fcc1d7b91bac97ba7963bf0 @@ -702,7 +702,7 @@ SIMPLE_OPTION(to, "to/clear-to", args_ve SIMPLE_OPTION(to, "to/clear-to", args_vector, gettext_noop("revision(s) to stop logging at")) -SIMPLE_OPTION(unknown, "unknown", bool, +SIMPLE_OPTION(unknown, "unknown/no-unknown", bool, gettext_noop("perform the operations for unknown files from workspace")) GLOBAL_SIMPLE_OPTION(version, "version", bool, @@ -715,7 +715,7 @@ OPTVAR(automate_inventory_opts, bool, no OPTVAR(automate_inventory_opts, bool, no_unchanged, false) OPTVAR(automate_inventory_opts, bool, no_corresponding_renames, false) -OPTION(automate_inventory_opts, no_ignored, false, "no-ignored", +OPTION(automate_inventory_opts, no_ignored, false, "no-ignored/ignored", gettext_noop("don't output ignored files")) #ifdef option_bodies { @@ -723,7 +723,7 @@ OPTION(automate_inventory_opts, no_ignor } #endif -OPTION(automate_inventory_opts, no_unknown, false, "no-unknown", +OPTION(automate_inventory_opts, no_unknown, false, "no-unknown/unknown", gettext_noop("don't output unknown files")) #ifdef option_bodies { @@ -731,7 +731,7 @@ OPTION(automate_inventory_opts, no_unkno } #endif -OPTION(automate_inventory_opts, no_unchanged, false, "no-unchanged", +OPTION(automate_inventory_opts, no_unchanged, false, "no-unchanged/unchanged", gettext_noop("don't output unchanged files")) #ifdef option_bodies {