From ede6f92c78f4c2e863b415884a3dfc3fad7f1c21 Mon Sep 17 00:00:00 2001 From: Pavel Belikov Date: Sun, 15 Oct 2017 21:51:42 +0300 Subject: [PATCH] add Options::Hidden --- args.hxx | 103 ++++++++++++++++++++++++++++--------------------------- test.cxx | 16 +++++++++ 2 files changed, 68 insertions(+), 51 deletions(-) diff --git a/args.hxx b/args.hxx index ff0e0dd..1af7491 100644 --- a/args.hxx +++ b/args.hxx @@ -381,10 +381,42 @@ namespace args } }; + enum class Options + { + /** Default options. + */ + None = 0x0, + + /** Flag can't be passed multiple times. + */ + Single = 0x01, + + /** Flag can't be omitted. + */ + Required = 0x02, + + /** Flag is excluded from help output. + */ + Hidden = 0x04, + }; + + inline Options operator | (Options lhs, Options rhs) + { + return static_cast(static_cast(lhs) | static_cast(rhs)); + } + + inline Options operator & (Options lhs, Options rhs) + { + return static_cast(static_cast(lhs) & static_cast(rhs)); + } + /** Base class for all match types */ class Base { + private: + const Options options; + protected: bool matched; const std::string help; @@ -394,9 +426,14 @@ namespace args #endif public: - Base(const std::string &help_) : matched(false), help(help_) {} + Base(const std::string &help_, Options options_ = {}) : options(options_), matched(false), help(help_) {} virtual ~Base() {} + Options GetOptions() const noexcept + { + return options; + } + virtual bool Matched() const noexcept { return matched; @@ -444,7 +481,7 @@ namespace args bool kickout; public: - NamedBase(const std::string &name_, const std::string &help_) : Base(help_), name(name_), kickout(false) {} + NamedBase(const std::string &name_, const std::string &help_, Options options_ = {}) : Base(help_, options_), name(name_), kickout(false) {} virtual ~NamedBase() {} virtual std::tuple GetDescription(const std::string &, const std::string &, const std::string &, const std::string &) const override @@ -454,6 +491,7 @@ namespace args std::get<1>(description) = help; return description; } + virtual std::string Name() const { return name; @@ -472,59 +510,25 @@ namespace args } }; - - enum class Options - { - /** Default options. - */ - None = 0x0, - - /** Flag can't be passed multiple times. - */ - Single = 0x01, - - /** Flag can't be omitted. - */ - Required = 0x02, - }; - - inline Options operator | (Options lhs, Options rhs) - { - return static_cast(static_cast(lhs) | static_cast(rhs)); - } - - inline Options operator & (Options lhs, Options rhs) - { - return static_cast(static_cast(lhs) & static_cast(rhs)); - } - /** Base class for all flag options */ class FlagBase : public NamedBase { - private: - const Options options; - protected: const Matcher matcher; public: - FlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, const bool extraError_ = false) : NamedBase(name_, help_), options(extraError_ ? Options::Single : Options()), matcher(std::move(matcher_)) {} + FlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, const bool extraError_ = false) : NamedBase(name_, help_, extraError_ ? Options::Single : Options()), matcher(std::move(matcher_)) {} - FlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_) : NamedBase(name_, help_), options(options_), matcher(std::move(matcher_)) {} + FlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_) : NamedBase(name_, help_, options_), matcher(std::move(matcher_)) {} virtual ~FlagBase() {} - Options GetOptions() const - { - return options; - } - virtual FlagBase *Match(const std::string &flag) { if (matcher.Match(flag)) { - if ((options & Options::Single) != Options::None && matched) + if ((GetOptions() & Options::Single) != Options::None && matched) { #ifdef ARGS_NOEXCEPT error = Error::Extra; @@ -542,7 +546,7 @@ namespace args virtual void Validate(const std::string &shortPrefix, const std::string &longPrefix) override { - if (!Matched() && (options & Options::Required) != Options::None) + if (!Matched() && (GetOptions() & Options::Required) != Options::None) { #ifdef ARGS_NOEXCEPT error = Error::Required; @@ -558,7 +562,7 @@ namespace args { if (matcher.Match(flag)) { - if ((options & Options::Single) != Options::None && matched) + if ((GetOptions() & Options::Single) != Options::None && matched) { #ifdef ARGS_NOEXCEPT error = Error::Extra; @@ -626,14 +630,11 @@ namespace args */ class PositionalBase : public NamedBase { - private: - const Options options; - protected: bool ready; public: - PositionalBase(const std::string &name_, const std::string &help_, Options options_ = Options::None) : NamedBase(name_, help_), options(options_), ready(true) {} + PositionalBase(const std::string &name_, const std::string &help_, Options options_ = Options::None) : NamedBase(name_, help_, options_), ready(true) {} virtual ~PositionalBase() {} bool Ready() @@ -641,11 +642,6 @@ namespace args return ready; } - Options GetOptions() const - { - return options; - } - virtual void ParseValue(const std::string &value_) = 0; virtual void Reset() noexcept override @@ -659,7 +655,7 @@ namespace args virtual void Validate(const std::string &, const std::string &) override { - if ((options & Options::Required) != Options::None && !Matched()) + if ((GetOptions() & Options::Required) != Options::None && !Matched()) { #ifdef ARGS_NOEXCEPT error = Error::Required; @@ -863,6 +859,11 @@ namespace args std::vector> descriptions; for (const auto &child: children) { + if ((child->GetOptions() & Options::Hidden) != Options::None) + { + continue; + } + if (const auto group = dynamic_cast(child)) { // Push that group description on the back if not empty diff --git a/test.cxx b/test.cxx index e8a7d81..67172b4 100644 --- a/test.cxx +++ b/test.cxx @@ -590,6 +590,22 @@ TEST_CASE("Required flags work as expected", "[args]") REQUIRE_THROWS_AS(parser3.ParseArgs(std::vector{}), args::RequiredError); } +TEST_CASE("Hidden options are excluded from help", "[args]") +{ + args::ArgumentParser parser1(""); + args::ValueFlag foo(parser1, "foo", "foo", {'f', "foo"}, args::Options::Hidden); + args::ValueFlag bar(parser1, "bar", "bar", {'b'}); + args::Group group(parser1, "group"); + args::ValueFlag foo1(group, "foo", "foo", {'f', "foo"}, args::Options::Hidden); + args::ValueFlag bar2(group, "bar", "bar", {'b'}); + + auto desc = parser1.GetChildDescriptions("", "", "", ""); + REQUIRE(desc.size() == 3); + REQUIRE(std::get<0>(desc[0]) == "b[bar]"); + REQUIRE(std::get<0>(desc[1]) == "group"); + REQUIRE(std::get<0>(desc[2]) == "b[bar]"); +} + #undef ARGS_HXX #define ARGS_TESTNAMESPACE #define ARGS_NOEXCEPT