Skip to content

Commit

Permalink
Merge pull request #34 from pavel-belikov/hidden-args
Browse files Browse the repository at this point in the history
Add Options::Hidden to exclude option from help
  • Loading branch information
Taylor C. Richberger authored Oct 15, 2017
2 parents 69547d2 + ede6f92 commit 5519963
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 51 deletions.
103 changes: 52 additions & 51 deletions args.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -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<Options>(static_cast<int>(lhs) | static_cast<int>(rhs));
}

inline Options operator & (Options lhs, Options rhs)
{
return static_cast<Options>(static_cast<int>(lhs) & static_cast<int>(rhs));
}

/** Base class for all match types
*/
class Base
{
private:
const Options options;

protected:
bool matched;
const std::string help;
Expand All @@ -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;
Expand Down Expand Up @@ -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<std::string, std::string> GetDescription(const std::string &, const std::string &, const std::string &, const std::string &) const override
Expand All @@ -454,6 +491,7 @@ namespace args
std::get<1>(description) = help;
return description;
}

virtual std::string Name() const
{
return name;
Expand All @@ -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<Options>(static_cast<int>(lhs) | static_cast<int>(rhs));
}

inline Options operator & (Options lhs, Options rhs)
{
return static_cast<Options>(static_cast<int>(lhs) & static_cast<int>(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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -626,26 +630,18 @@ 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()
{
return ready;
}

Options GetOptions() const
{
return options;
}

virtual void ParseValue(const std::string &value_) = 0;

virtual void Reset() noexcept override
Expand All @@ -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;
Expand Down Expand Up @@ -863,6 +859,11 @@ namespace args
std::vector<std::tuple<std::string, std::string, unsigned int>> descriptions;
for (const auto &child: children)
{
if ((child->GetOptions() & Options::Hidden) != Options::None)
{
continue;
}

if (const auto group = dynamic_cast<Group *>(child))
{
// Push that group description on the back if not empty
Expand Down
16 changes: 16 additions & 0 deletions test.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,22 @@ TEST_CASE("Required flags work as expected", "[args]")
REQUIRE_THROWS_AS(parser3.ParseArgs(std::vector<std::string>{}), args::RequiredError);
}

TEST_CASE("Hidden options are excluded from help", "[args]")
{
args::ArgumentParser parser1("");
args::ValueFlag<int> foo(parser1, "foo", "foo", {'f', "foo"}, args::Options::Hidden);
args::ValueFlag<int> bar(parser1, "bar", "bar", {'b'});
args::Group group(parser1, "group");
args::ValueFlag<int> foo1(group, "foo", "foo", {'f', "foo"}, args::Options::Hidden);
args::ValueFlag<int> 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
Expand Down

0 comments on commit 5519963

Please sign in to comment.