# # # patch "option.cc" # from [6697c789f4b6dd082bbab6c2c7bea70dc549b308] # to [5f78f36e5c5a6ba6000ed6bba4354965cd96636a] # # patch "option.hh" # from [a120f75cc822a8ff7a0e0602d2385f3d730f2588] # to [4b8b3b06e05e716358a3da600f0c0a948104af8c] # ============================================================ --- option.cc 6697c789f4b6dd082bbab6c2c7bea70dc549b308 +++ option.cc 5f78f36e5c5a6ba6000ed6bba4354965cd96636a @@ -53,9 +53,15 @@ bad_arg_internal::bad_arg_internal(strin -void splitname(char const * f, string & name, string & n) +void splitname(char const * f, string & name, string & n, string & cancel) { string from(f); + if (from.find("/") != string::npos) + { + string::size_type slash = from.find("/"); + cancel = from.substr(slash+1); + from.erase(slash); + } // from looks like "foo" or "foo,f" string::size_type comma = from.find(','); name = from.substr(0, comma); @@ -86,8 +92,10 @@ concrete_option::concrete_option(char co boost::function reset) { description = desc; - splitname(names, longname, shortname); + splitname(names, longname, shortname, cancelname); I((desc && desc[0]) || !longname.empty() || !shortname.empty()); + // not sure how to display if it can only be reset (and what would that mean?) + I((!longname.empty() || !shortname.empty()) || cancelname.empty()); // If an option has a name (ie, can be set), it must have a setter function I(set || (longname.empty() && shortname.empty())); has_arg = arg; @@ -101,6 +109,8 @@ bool concrete_option::operator<(concrete return longname < other.longname; if (shortname != other.shortname) return shortname < other.shortname; + if (cancelname != other.cancelname) + return cancelname < other.cancelname; return description < other.description; } @@ -272,6 +282,8 @@ get_by_name(std::set co by_name.insert(make_pair(i->longname, *i)); if (!i->shortname.empty()) by_name.insert(make_pair(i->shortname, *i)); + if (!i->cancelname.empty()) + by_name.insert(make_pair(i->cancelname, *i)); } return by_name; } @@ -287,6 +299,7 @@ void concrete_option_set::from_command_l concrete_option o; string name; arg_type arg; + bool is_cancel; bool separate_arg(false); if (idx(args,i)() == "--" || seen_dashdash) { @@ -299,6 +312,7 @@ void concrete_option_set::from_command_l name = "--"; o = getopt(by_name, name); arg = idx(args,i); + is_cancel = false; } else if (idx(args,i)().substr(0,2) == "--") { @@ -309,10 +323,11 @@ void concrete_option_set::from_command_l name = idx(args,i)().substr(2, equals-2); o = getopt(by_name, name); - if (!o.has_arg && equals != string::npos) + is_cancel = (name == o.cancelname); + if ((!o.has_arg || is_cancel) && equals != string::npos) throw extra_arg(name); - if (o.has_arg) + if (o.has_arg && !is_cancel) { if (equals == string::npos) { @@ -330,6 +345,8 @@ void concrete_option_set::from_command_l name = idx(args,i)().substr(1,1); o = getopt(by_name, name); + is_cancel = (name == o.cancelname); + I(!is_cancel); if (!o.has_arg && idx(args,i)().size() != 2) throw extra_arg(name); @@ -351,6 +368,7 @@ void concrete_option_set::from_command_l name = "--"; o = getopt(by_name, name); arg = idx(args,i); + is_cancel = false; } if (allow_xargs && (name == "xargs" || name == "@")) @@ -373,8 +391,16 @@ void concrete_option_set::from_command_l ++i; try { - if (o.setter) - o.setter(arg()); + if (!is_cancel) + { + if (o.setter) + o.setter(arg()); + } + else + { + if (o.resetter) + o.resetter(); + } } catch (boost::bad_lexical_cast) { @@ -423,7 +449,7 @@ void concrete_option_set::from_key_value } // Get the non-description part of the usage string, -// looks like "--long [ -s ] ". +// looks like "--long [ -s ] / --cancel". static string usagestr(concrete_option const & opt) { string out; @@ -435,8 +461,17 @@ static string usagestr(concrete_option c out = "--" + opt.longname; else if (!opt.shortname.empty()) out = "-" + opt.shortname; - else - return ""; + + if (out.empty()) + return out; + + if (!opt.cancelname.empty()) + { + if (!out.empty()) + out += " / "; + out += "--" + opt.cancelname; + } + if (opt.has_arg) return out + " "; else ============================================================ --- option.hh a120f75cc822a8ff7a0e0602d2385f3d730f2588 +++ option.hh 4b8b3b06e05e716358a3da600f0c0a948104af8c @@ -78,7 +78,7 @@ namespace option { }; // Split a "long,s" option name into long and short names. - void splitname(char const * from, std::string & name, std::string & n); + void splitname(char const * from, std::string & name, std::string & n, std::string & cancelname); // An option that can be set and reset. struct concrete_option @@ -86,6 +86,7 @@ namespace option { char const * description; std::string longname; std::string shortname; + std::string cancelname; bool has_arg; boost::function setter; boost::function resetter; @@ -246,7 +247,7 @@ namespace option { { concrete_option out; out.description = description; - splitname(names, out.longname, out.shortname); + splitname(names, out.longname, out.shortname, out.cancelname); out.has_arg = has_arg; if (setter)